999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

VB與Lua交互調用的研究與實現

2015-09-28 07:21:02黃皓中山市廣播電視大學中山528400
現代計算機 2015年30期
關鍵詞:定義

黃皓(中山市廣播電視大學,中山 528400)

VB與Lua交互調用的研究與實現

黃皓
(中山市廣播電視大學,中山 528400)

0 引言

VB和Lua都是當今廣為流行的程序設計語言。Lua是簡潔、輕量、可擴展的腳本語言,1993年誕生于巴西里約熱內盧天主教大學。Lua的優點在于:可嵌入、跨平臺、運行高效、語法簡潔、免費開源、小巧輕便。近年來,Lua除了游戲開發以外,還廣泛地應用于其他領域。

VB是Microsoft的可視化、基于對象和采用事件驅動方式的快速應用程序開發 (RAD)工具。它源自于BASIC語言,簡單易學;擁有圖形用戶界面(GUI),可使用Win32 API函數、動態鏈接庫(DLL)、對象的鏈接與嵌入(OLE)、開放式數據連接(ODBC)等技術,功能強,開發效率高。

VB和Lua各有優勢,如能取長補短,互為補充,則在程序設計中可以更高效、靈活地達成目標。例如使用VB來進行GUI界面設計、訪問數據庫,而Lua進行程序配置和字符串的處理等。

1 宿主語言與Lua的交互

Lua是用C編寫的,在設計時就以嵌入宿主語言C/C++程序為目標,因此其與宿主語言的交互由一系列C API構成,所有的API在lua.h、lauxlib.h、lualib.h三個C頭文件中定義。VB的數據類型以及函數使用方式與

C相似,其與Lua的交互調用可以參照C/C++的方式。

Lua與宿主程序通過一個虛擬的堆棧進行數據交換。缺省的堆棧大小由LUA_MINSTACK定義,一般為20,可以使用lua_checkstack函數來擴大可用堆棧的尺寸。Lua遵循FILO規則使用堆棧。而宿主語言可以通過索引使用棧中元素。索引值為正表示棧中的絕對位置(從1開始);索引值為負則指從棧頂開始的偏移量。如堆棧有n個元素,那么索引1或-n表示第一個被壓入堆棧的元素(棧底),而索引n或-1則指最后一個元素(棧頂)。索引index在1到棧頂之間有效,0不是有效的索引值。

(1)壓入堆棧

lua_getglobal(lua_State*L,const char*name)

把全局變量name里的值壓入堆棧。

lua_push*將C程序中的數據放入棧中。(*可以是nil,number,integer,string,boolean,userdata,thread,cclosure等,下同)

(2)彈出堆棧

lua_pop(lua_State*L,int n);

從堆棧中彈出n個元素。此操作僅修改棧頂位置,并不能得到相應數據。

(3)棧元素查詢

返回給定索引處的值的類型,返回值作為常量定義在lua.h中,如LUA_TNUMBER等。

lua_is*當對象與所給類型兼容的時候函數返回1,其他情況返回0。除了lua_isboolean,它只針對布爾值時才會成功,否則將是無用的。這些函數對于無效引用返回0。

(4)從棧中取元素

使用lua_to*將指定的索引處的的Lua類型值轉換為一個C中的值。此操作并不修改棧頂位置。

通過兩個步驟來實現:

①Lua全局變量壓入堆棧:lua_getglobal(L,"變量名");

②根據棧頂數據的數據類型lua_type,取棧頂數據:lua_to*

可以有三種調用方式:

(1)執行一個語句塊

Lua API直接支持執行一個語句塊,使用luaL_dostring(L,“Lua語句塊”)

(2)執行一個文件

①將磁盤中的Lua源程序文件裝入:luaL_loadfile (L,fn);

②以保護方式執行該塊:lua_pcall(L,0,0,0);

在執行前,Lua會對源文件進行編譯,生成中間代碼。

(3)調用文件中的函數

Lua的函數和普通變量一樣也是First Class Variable,可以看作函數指針變量參與棧操作。因此調用過程分為如下幾個步驟:

①被調用的Lua函數變量入棧;

②將函數需要的參數入棧,入棧順序按照參數被聲明的順序;

③告知Lua虛擬機入棧參數的個數、函數返回值的個數,并調用此Lua函數;

④從棧頂獲得返回值,先返回的先入棧,然后將返回值顯式出棧。

(1)注冊宿主子程序

①聲明并定義一個C函數,函數原型為typedef int (*lua_CFunction)(lua_State*L),該函數有一個參數,而函數的返回值為壓入虛擬堆棧的數據個數;

②用字符串給該C函數取一個在Lua中調用的名稱,壓入堆棧;

③將函數指針入棧;

④調用Lua API,將上述的名稱與函數指針關聯。在VB中,第①步定義的函數應該為如下形式:

'從虛擬棧中取參數;參數是按左右順序壓入堆棧的。'處理;

'將結果按返回順序壓入虛擬棧;

第③步中,可以使用AddressOf myFun來取得VB子程序的地址,而VBS沒有AddressOf,所以VBS不能注冊子程序并讓其回調。

(2)在Lua中調用執行

Lua使用注冊的函數名來調用宿主子程序。當調用宿主C函數時,Lua使用一個獨立的新棧,其中包含了Lua傳遞給C函數的所有參數,而C函數則把要返回的結果也放入堆棧以返回給調用者。被調用的C函數不能訪問Lua虛擬機本次調用之外的堆棧中的數據。

2 在VB中使用Lua

一般來說,代碼復用有靜態編譯和動態鏈接兩種方式。Lua是開源的,如果宿主程序使用C/C++語言編寫,那么可以將Lua與宿主源程序一同編譯,Lua與宿主合為一個整體。VB顯然不能采用這一方式。

宿主程序也可以動態鏈接Lua庫中的函數。在這種方式下Lua先獨立編譯為DLL文件,然后宿主程序在運行時與Lua動態鏈接。VB以下面的格式使用DLL中的API:

Declare function函數名稱libs“動態鏈接庫文件路徑”alias“庫函數名”(參數列表)as返回類型

從www.lua.org下載Lua源程序包后,編譯(也可直接在網上下載)得到Lua.dll動態鏈接庫,然后把lua.h、lauxlib.h、lualib.h三個C頭文件中定義的API信息轉換為VB可用的模塊文件,在需要使用Lua的VB工程中導入模塊。

(1)VB使用的模塊文件

Lua頭文件中定義了許多API,在下面的模塊文件中,僅引入供后面類模塊必須使用的API。由于Lua各個版本之間存在差異,頭文件與相應的DLL對應,不能混用。本模塊以Lua5.1版本為例。

以下是模塊文件Mudule1.bas應該包含的內容:

Public Declare Sub CopyMemory Lib"kernel32.dll"Alias" RtlMoveMemory"(Destination As Any,Source As Any,ByVal Length As Long)

該Win32 API用于后面的lua_tostring函數。

在模塊中還用到了lua.h頭文件中定義的幾個常量。例如:

#define LUA_GLOBALSINDEX(-10002)

在VB中轉換為:

Public Const LUA_GLOBALSINDEX As Long=(-10002)

在lua.h中找到LUA_MULTRET、LUA_TBOOLEAN、LUA_TNUMBER、LUA_TSTRING參照以上方式進行定義。

模塊使用了一些Lua常用的API,如:

LUALIB_API void(luaL_openlibs)(lua_State*L);

在VB中轉換為:

Public Declare Function luaL_openlibs Lib"lua"(ByVal h As Long)As Long

在 lua.h中找到 lua_close、lua_getfield、lu a_setfield、lua_pcall、lua_pushboolean、lua_pushnumber、lua_pushstring、lua_pushcclosure、lua_settable、lua_type、lua_toboolean、lua_tonumber、lua_tolstring、lua_settop,在lauxlib.h中找到 luaL_newstate、luaL_loadstring、luaL_loadfile,參照上述方式進行定義。注意函數返回類型除了lua_tonumber為Double外,其余均為Long;參數類型除了const char*應定義為String外,其余均定義為Long;參數調用方式為ByVal按值調用。

在lua.h還定義了一些宏,例如:

#define lua_getglobal(L,s)lua_getfield(L,LUA_GLOBALSINDEX,(s))

這些API在Lua.dll中無導出函數,VB需用函數來實現:

Public Function lua_getglobal(ByVal h As Long,s As String)As Long

lua_getglobal=lua_getfield(h,LUA_GLOBALSINDEX,s)End Function

參照以上方法用VB對 lua_setglobal、lua_pushcfunction、lua_pop編寫相應函數。而lua_tostring處理相對較多,對應VB函數如下:

在lauxlib.h中還有一個要用的API,對應VB函數如下:

(2)VB使用的類模塊

Lua提供的API很多,對于宿主程序來說,未必會使用到全部的功能,最核心的無非是調用Lua函數、Lua調用宿主函數、運行Lua語句塊、訪問Lua全局變量等交互。因此,為了方便進行處理,我們可以建立以下類模塊。限于篇幅,類模塊將處理的數據類型縮減為數值、字符串和布爾三種常用類型,實際應用時可根據需要進行增加。

下面是類模塊文件Class1.cls的主要內容:

Dim L As Long'Lua虛擬機指針

Public Function LuaOpen()As Long'新建虛擬機,代碼略

Public Function LuaClose()As Long'關閉虛擬機,代碼略

Public Function LuaPushValue(ByVal value As String)As Long'根據參數字串內容壓入數據數值、字串或布爾值

If LCase(value)="false"Then

LuaPushValue=lua_pushboolean(L,0)

ElseIf LCase(value)="true"Then

LuaPushValue=lua_pushboolean(L,1)

Else

LuaPushValue=lua_pushstring(L,value)

End If

Else

LuaPushValue=lua_pushnumber(L,v)

End If

End Function

Public Function LuaPopValue()As String'返回棧頂內容字串

Select Case lua_type(L,-1)

Case LUA_TNUMBER

LuaPopValue=Str(lua_tonumber(L,-1))

Case LUA_TSTRING

LuaPopValue=lua_tostring(L,-1)

Case LUA_TBOOLEAN

LuaPopValue=IIf(lua_toboolean(L,-1),"True"," False")

End Select

lua_pop L,1

End Function

Public Function LuaGetVar(ByVal varname As String)As String'取變量內容,代碼略

Public Function LuaSetVar(ByVal varname As String,By-Val value As String)As Long'設置變量值,代碼略

Public Function LuaDoString(ByVal s As String)As Long'執行字符串中的語句塊,代碼略

Public Function LuaDoFile(ByVal fn As String)As Long'執行文件,代碼略

Public Function LuaCall(ByVal fun As String,ByVal para As String,ByVal nRes As Long)As String'調用Lua中的函數

Dim iErr As Long,nPara As Long,A ()As String,i As Long

lua_getglobal L,fun

A=Split(para,",")'參數para用“,”分隔

nPara=UBound(A)

If nPara<0 Then nPara=0:ReDim A (0):A(0)= para

For i=0 To nPara:Call LuaPushValue(A(i)):Next

iErr=lua_pcall(L,nPara+1,nRes,0)'nRes為結果個數

LuaCall=""

For i=1 To nRes

LuaCall=LuaPopValue()+","+LuaCall

Next

LuaCall=Left(LuaCall,Len(LuaCall)-1)

End Function

Public Function LuaReg(ByVal fun As String,ByVal lp As Long)As Long'注冊VB函數,lp為VB函數指針

lua_pushstring L,fun

lua_pushcfunction L,lp

LuaReg=lua_settable(L,LUA_GLOBALSINDEX)

End Function

(3)實例

將Lua.dll復制到System32目錄中,新建工程“標準EXE”,導入模塊Mudule1.bas和類模塊Class1.cls(命名為LuaClass),就可以在VB程序中使用Lua了。如在窗體Form1中,新建一個按鈕Command1,輸入以下代碼:

Private Sub Command1_Click()

Dim result As String

o.LuaOpen

o.LuaReg"vb",AddressOf ex

o.LuaDoString("function f1(a,b)x,y=vb(a,b)return x,y end c=math.sin(1/2);")

result=o.LuaCall("f1","100,200",2)

MsgBox result,,o.LuaGetVar("c")

o.LuaClose

End Sub

新建一個模塊,輸入以下代碼:

Public o As New LuaClass

Function ex(ByVal L As Long)As Long

Dim x As Long,y As Long

x=o.LuaPopValue:y=o.LuaPopValue

o.LuaPushValue x:o.LuaPushValue y:ex=2

End Function

運行并點擊Command1,可得到運行結果。

3 封裝Lua到COM

ASP、WSH、VBS等腳本語言不能直接使用DLL,我們可以將上述模塊封裝為COM組件,那么這些高級語言就可以通過COM使用Lua來進行擴展了。

在VB中新建工程“ActiveX DLL”,導入模塊Mud-ule1.bas和類模塊Class1.cls(命名為LuaClass),在菜單“工程”-“屬性”處,更改工程名為“Lua”,點擊“文件”-“生成dll”。假設生成c:LuaX.dll,運行regsvr32 c:luaX. dll,復制Lua.dl1到System32中,然后上述腳本語言就可以通過COM使用Lua了。如建立并運行如下腳本文件Test.vbs:

Set o=CreateObject("Lua.LuaClass")

o.LuaOpen

o.LuaDoString("function f1(a,b)return b,a end c=string. sub(math.sin(1/2),1,8)")

x=o.LuaGetVar("c"):s=o.LuaCall("f1","100,200",2)

msgbox s,,x

o.LuaClose

4 結語

在國外TIOBE軟件廠商發布2014年7月份編程語言排行榜中,VB由2013年的第7位升高到第5位,占4.341%;而Lua排名36位,占0.332%。這說明即使在Microsoft轉向.NET平臺多年以后,VB依然受到編程者的喜愛,而Lua的發展潛力很大。在VB中調用Lua,結合VB的快速開發特性和Lua的靈活性,我們開發的應用將更有彈性,而對于Lua接口API的再封裝,無疑為ASP等腳本語言使用Lua打開了一扇大門。

[1]Roberto Ierusalimschy.Lua程序設計[M].2版.周惟迪,譯.北京:電子工業出版社,2008.

[2]鄧正陽,陳和平,蘇鵬.動態腳本語言Lua與C++交互方法的研究與實現[J].計算機系統應用,2010,19(5):198-201.

[3]魏江平.LUA腳本語言在游戲引擎中的應用分析[J].微型電腦應用,2008,24(4):22-23.

[4]Lablua at PUC-Rio.Lua 5.1 Reference Manual[EB/OL].(2011-09-28)[2014-1-28].http://www.lua.org/manual/5.1/.

[5]張帆.可重構軟件平臺構建原理與應用研究[D].武漢理工大學,2012.

[6]鄧楠喬,秦開宇,金燕華.基于Lua的面向組件程序設計研究[J].中國高新技術企業,2010,(9):3-4.

[7]Marco Pontello.PowerBLua-A Lua5.0 wrapper for PowerBASIC[EB/OL].(2007-08-03).http://mark0.net/code-powerblua-e.html.

[8]汪君鵬,李宥謀.基于Lua腳本技術的網絡化測控系統設計[J].西安郵電大學學報,2013,18(1):90-94.

[9]苗新亮,劉棟,雷波,楊遠輝.Lua腳本語言在安全設備管理系統中的應用[J].信息安全與通信保密,2014,(2):92-94.

[10]孫秀梅,鞏建華.Visual Basic開發實戰1200例(第1卷)[M].北京:清華大學出版社,2011.

VB;Lua;COM

Research and Implementation of Interaction Between VB and Lua

HUANG Hao
(Zhongshan Radio&Television University,Zhongshan 528400)

1007-1423(2015)30-0068-05

10.3969/j.issn.1007-1423.2015.30.019

黃皓(1969-),男,廣西桂林人,講師,碩士,研究方向為計算機程序設計、遠程教育技術

2015-09-15

2015-09-30

VB和Lua都是常用的編程語言,為了結合利用VB和Lua各自的優點,快速、高效、靈活地進行應用程序開發,通過對C與Lua之間交互模式的研究分析,提出VB與Lua交互調用的方法,并進一步將VB調用Lua的接口封裝為COM組件,以隱藏細節信息和簡化調用接口,可支持更多其他編程語言如ASP、VBS等調用Lua。實踐證明,這種VB 與Lua的交互調用方式是有效的、易于使用的。

VB;Lua;COM

VB and Lua are commonly used programming language,in order to take the advantage of VB and Lua and develop application fast,efficiently and flexibly,analyses the interactive mode between C and Lua,then presents a method for VB to call Lua,finally discusses about packaging the interface into a COM object,which hides detail information and simplifies the interface,and supports more programming languages to use Lua.Practice has proved that the method of VB interacting with Lua is effective,easy to use.

猜你喜歡
定義
以愛之名,定義成長
活用定義巧解統計概率解答題
例談橢圓的定義及其應用
題在書外 根在書中——圓錐曲線第三定義在教材和高考中的滲透
永遠不要用“起點”定義自己
海峽姐妹(2020年9期)2021-01-04 01:35:44
嚴昊:不定義終點 一直在路上
華人時刊(2020年13期)2020-09-25 08:21:32
定義“風格”
成功的定義
山東青年(2016年1期)2016-02-28 14:25:25
有壹手——重新定義快修連鎖
修辭學的重大定義
當代修辭學(2014年3期)2014-01-21 02:30:44
主站蜘蛛池模板: 亚洲福利视频网址| 日本成人精品视频| 国产美女一级毛片| 亚洲成a人在线观看| 国产成人在线无码免费视频| 欧美a√在线| 国产成人AV男人的天堂| 亚洲国产成人综合精品2020| 中文字幕乱码二三区免费| 亚洲国产清纯| 久久91精品牛牛| 亚洲精品成人福利在线电影| AV在线麻免费观看网站 | 成人免费午间影院在线观看| 国产一级毛片yw| 又大又硬又爽免费视频| 色哟哟精品无码网站在线播放视频| 欧美日韩久久综合| 亚洲男人的天堂在线| 中文国产成人久久精品小说| 中国精品自拍| 伊人激情综合| 青青网在线国产| 五月天在线网站| 久久久受www免费人成| 日韩欧美中文| www.日韩三级| 操美女免费网站| 精品午夜国产福利观看| 欧美精品不卡| 永久免费AⅤ无码网站在线观看| 99热国产这里只有精品9九| 香蕉色综合| 成人综合在线观看| 欧美精品1区2区| 找国产毛片看| 欧美日本在线一区二区三区| 日本黄色a视频| 亚洲日韩图片专区第1页| 欧美成人综合在线| 国产哺乳奶水91在线播放| 亚洲v日韩v欧美在线观看| 欧美日韩在线国产| 久久香蕉国产线看观看式| 丁香婷婷综合激情| 一本色道久久88| 亚洲成a人片在线观看88| 亚洲日韩在线满18点击进入| 久久婷婷人人澡人人爱91| 欧美精品一区二区三区中文字幕| 日本成人精品视频| 白浆免费视频国产精品视频| 欧美爱爱网| 野花国产精品入口| AV天堂资源福利在线观看| 亚洲国产成熟视频在线多多| 国产人碰人摸人爱免费视频| 成人毛片在线播放| 亚洲三级色| 天天综合网站| 91丨九色丨首页在线播放| 亚洲AV成人一区国产精品| 伊人久久大香线蕉aⅴ色| 国产乱子精品一区二区在线观看| 中文字幕在线观| 人禽伦免费交视频网页播放| 综合网天天| 丁香六月综合网| 国产日产欧美精品| 九九久久精品免费观看| 这里只有精品在线| 国产成人亚洲综合a∨婷婷| 日韩无码视频播放| 91精品最新国内在线播放| 色亚洲成人| 特级精品毛片免费观看| 波多野结衣爽到高潮漏水大喷| 婷婷在线网站| 性喷潮久久久久久久久| 国产精品99久久久久久董美香| 国产成人精品视频一区二区电影 | 亚洲AV永久无码精品古装片|