PowerBuilder編程新思惟1:擴展(Lua)

前言

PowerBuilder做爲開發工具退出一線行列已經好久了,在2019年來談這樣一款老舊的編程工具是否有意義?誠然,PB有着太多硬傷,但仍是有它的用武之地的。並且今天講的這個「新思惟」大部份內容是我在其它地方沒有見過的,包含一些比較新的思想,希望可以給各位讀者帶來耳目一新的感受和有價值的參考。編程

因爲內容比較多,打算合起來做爲一個庫,名字叫PowerPlume,中文爲「孔雀翎」,古龍書中強大又美麗的武器。json

 

PowerBuilder編程新思惟1:擴展(Lua)

PB環境是封閉的,致使有些部分的能力極弱,依賴開發各種DLL和擴展(PBNI)。把腳本語言引擎引入到PB中,有着不少的現實意義,最大的好處就是可以直接利用腳本語言的各種資源與源碼,不用再重複開發。api

常見的腳本語言有JS、Python、Ruby等,爲何選擇Lua?由於小、由於快。JS因爲歷史緣由,太龐大了。Python和Ruby也不是很小巧。並且環境配置複雜。Lua小巧,接口也很友好,資源也豐富。架構

接口方面,選擇PBNI而不是直接使用DLL,是由於須要處理一些指針和支持PowerObject,整體與LuaApi基本一致。socket

global type n_lua from nonvisualobject native "pblua105.dll"
public function long register(string name, powerobject obj)
public function long setglobal(string name)
public function long getglobal(string name)
public function long setfield(long idx, string key)
public function long getfield(long idx, string key)
public function long pushnil()
public function long pushboolean(boolean value)
public function long pushlong(long value)
public function long pushdouble(double value)
public function long pushstring(string value)
public function long pushpowerobject(powerobject value)
public function long toboolean(long idx, ref boolean value)
public function long tolong(long idx, ref long value)
public function long todouble(long idx, ref double value)
public function long tostring(long idx, ref string value)
public function long topowerobject(long idx, ref powerobject value)
public function boolean isboolean(long idx)
public function boolean islong(long idx)
public function boolean isdouble(long idx)
public function boolean isstring(long idx)
public function boolean ispowerobject(long idx)
public function boolean isnil(long idx)
public function boolean istable(long idx)
public function long spop(long n)
public function long scopy(long idx)
public function long sinsert(long idx)
public function long sremove(long idx)
public function long sreplace(long idx)
public function long sgettop()
public function long createtable(long arr, long rec)
public function long settable(long idx)
public function long gettable(long idx)
public function long setmetatable(long idx)
public function long nextkey(long idx)
public function long docall(long args, long results)
public function long dofile(string path)
public function long dostring(string str)
public function long enablecall(boolean ui)
end type

 

最早實現的功能是在Lua中很簡單,PB卻沒法提供的功能——HashTable。工具

實例:function integer of_map_set (string as_table, string as_key, powerobject an_value)oop

在Lua接口基礎上,添加了pushpowerobject這個接口,以處理PB對象。開發工具

int ret
ret = api.getglobal(as_table)
if (ret = LUA_TNIL) then
    api.createtable(0, 0);
elseif (ret <> LUA_TTABLE) then
    return FAILURE
end if

api.pushstring(as_key)
api.pushpowerobject(an_value)
api.settable(-3);

if (ret = LUA_TNIL) then
    api.setglobal(as_table)
end if

return SUCCESS

 

其次,必須利用Lua中比較成熟的資源,能夠在https://luarocks.org/上查找下載數較多的模塊,放入lib\lua目錄下便可require。須要注意的是咱們使用的是最新的Lua53,有些庫可能不兼容。在源碼中已經放入socket(http,ftp,stmp),xml,json庫。後續會陸續補上相關的封裝接口。
ui

實例:使用cjson模塊解析jsonlua

 1 string res
 2 
 3 i_lua.api.dostring("return require('cjson')")
 4 i_lua.api.pushstring('decode')
 5 i_lua.api.gettable(-2)
 6 
 7 if (not i_lua.api.isfunction(-1)) then
 8     messagebox("","error")
 9 end if
10 
11 i_lua.api.pushstring(mle_json.text)
12 i_lua.api.docall(1,1)
13 
14 i_lua.api.pushstring("sites")
15 i_lua.api.gettable(-2)
16 
17 string key,val
18 integer idx
19 idx = i_lua.api.sgettop()
20 
21 i_lua.api.pushnil()
22 do while i_lua.api.nextkey(idx)<>0
23     i_lua.api.pushstring("name")
24     i_lua.api.gettable(-2)
25     i_lua.api.tostring(-1, val)
26     i_lua.api.spop(2)
27     tv_1.InsertItemFirst(0,val,1)
28 loop
29 
30 i_lua.api.spop(3)

 

另外,在構建PowerPlume這個庫的時候,總體架構在Lua這個模塊之上,主要是利用其HashTable這個功能。

 

效果及源碼

 

 

 源碼: PowerPlumeDemoV0.1.1.rar

 提供了PB10.5 PB11.5 PB12.5三個版本

 

<本節完>

相關文章
相關標籤/搜索