亚洲免费av电影一区二区三区,日韩爱爱视频,51精品视频一区二区三区,91视频爱爱,日韩欧美在线播放视频,中文字幕少妇AV,亚洲电影中文字幕,久久久久亚洲av成人网址,久久综合视频网站,国产在线不卡免费播放

        ?

        VB與Lua交互調(diào)用的研究與實(shí)現(xiàn)

        2015-09-28 07:21:02黃皓中山市廣播電視大學(xué)中山528400
        現(xiàn)代計(jì)算機(jī) 2015年30期
        關(guān)鍵詞:定義

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

        VB與Lua交互調(diào)用的研究與實(shí)現(xiàn)

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

        0 引言

        VB和Lua都是當(dāng)今廣為流行的程序設(shè)計(jì)語(yǔ)言。Lua是簡(jiǎn)潔、輕量、可擴(kuò)展的腳本語(yǔ)言,1993年誕生于巴西里約熱內(nèi)盧天主教大學(xué)。Lua的優(yōu)點(diǎn)在于:可嵌入、跨平臺(tái)、運(yùn)行高效、語(yǔ)法簡(jiǎn)潔、免費(fèi)開源、小巧輕便。近年來(lái),Lua除了游戲開發(fā)以外,還廣泛地應(yīng)用于其他領(lǐng)域。

        VB是Microsoft的可視化、基于對(duì)象和采用事件驅(qū)動(dòng)方式的快速應(yīng)用程序開發(fā) (RAD)工具。它源自于BASIC語(yǔ)言,簡(jiǎn)單易學(xué);擁有圖形用戶界面(GUI),可使用Win32 API函數(shù)、動(dòng)態(tài)鏈接庫(kù)(DLL)、對(duì)象的鏈接與嵌入(OLE)、開放式數(shù)據(jù)連接(ODBC)等技術(shù),功能強(qiáng),開發(fā)效率高。

        VB和Lua各有優(yōu)勢(shì),如能取長(zhǎng)補(bǔ)短,互為補(bǔ)充,則在程序設(shè)計(jì)中可以更高效、靈活地達(dá)成目標(biāo)。例如使用VB來(lái)進(jìn)行GUI界面設(shè)計(jì)、訪問數(shù)據(jù)庫(kù),而Lua進(jìn)行程序配置和字符串的處理等。

        1 宿主語(yǔ)言與Lua的交互

        Lua是用C編寫的,在設(shè)計(jì)時(shí)就以嵌入宿主語(yǔ)言C/C++程序?yàn)槟繕?biāo),因此其與宿主語(yǔ)言的交互由一系列C API構(gòu)成,所有的API在lua.h、lauxlib.h、lualib.h三個(gè)C頭文件中定義。VB的數(shù)據(jù)類型以及函數(shù)使用方式與

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

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

        (1)壓入堆棧

        lua_getglobal(lua_State*L,const char*name)

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

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

        (2)彈出堆棧

        lua_pop(lua_State*L,int n);

        從堆棧中彈出n個(gè)元素。此操作僅修改棧頂位置,并不能得到相應(yīng)數(shù)據(jù)。

        (3)棧元素查詢

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

        lua_is*當(dāng)對(duì)象與所給類型兼容的時(shí)候函數(shù)返回1,其他情況返回0。除了lua_isboolean,它只針對(duì)布爾值時(shí)才會(huì)成功,否則將是無(wú)用的。這些函數(shù)對(duì)于無(wú)效引用返回0。

        (4)從棧中取元素

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

        通過(guò)兩個(gè)步驟來(lái)實(shí)現(xiàn):

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

        ②根據(jù)棧頂數(shù)據(jù)的數(shù)據(jù)類型lua_type,取棧頂數(shù)據(jù):lua_to*

        可以有三種調(diào)用方式:

        (1)執(zhí)行一個(gè)語(yǔ)句塊

        Lua API直接支持執(zhí)行一個(gè)語(yǔ)句塊,使用luaL_dostring(L,“Lua語(yǔ)句塊”)

        (2)執(zhí)行一個(gè)文件

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

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

        在執(zhí)行前,Lua會(huì)對(duì)源文件進(jìn)行編譯,生成中間代碼。

        (3)調(diào)用文件中的函數(shù)

        Lua的函數(shù)和普通變量一樣也是First Class Variable,可以看作函數(shù)指針變量參與棧操作。因此調(diào)用過(guò)程分為如下幾個(gè)步驟:

        ①被調(diào)用的Lua函數(shù)變量入棧;

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

        ③告知Lua虛擬機(jī)入棧參數(shù)的個(gè)數(shù)、函數(shù)返回值的個(gè)數(shù),并調(diào)用此Lua函數(shù);

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

        (1)注冊(cè)宿主子程序

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

        ②用字符串給該C函數(shù)取一個(gè)在Lua中調(diào)用的名稱,壓入堆棧;

        ③將函數(shù)指針入棧;

        ④調(diào)用Lua API,將上述的名稱與函數(shù)指針關(guān)聯(lián)。在VB中,第①步定義的函數(shù)應(yīng)該為如下形式:

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

        '將結(jié)果按返回順序壓入虛擬棧;

        第③步中,可以使用AddressOf myFun來(lái)取得VB子程序的地址,而VBS沒有AddressOf,所以VBS不能注冊(cè)子程序并讓其回調(diào)。

        (2)在Lua中調(diào)用執(zhí)行

        Lua使用注冊(cè)的函數(shù)名來(lái)調(diào)用宿主子程序。當(dāng)調(diào)用宿主C函數(shù)時(shí),Lua使用一個(gè)獨(dú)立的新棧,其中包含了Lua傳遞給C函數(shù)的所有參數(shù),而C函數(shù)則把要返回的結(jié)果也放入堆棧以返回給調(diào)用者。被調(diào)用的C函數(shù)不能訪問Lua虛擬機(jī)本次調(diào)用之外的堆棧中的數(shù)據(jù)。

        2 在VB中使用Lua

        一般來(lái)說(shuō),代碼復(fù)用有靜態(tài)編譯和動(dòng)態(tài)鏈接兩種方式。Lua是開源的,如果宿主程序使用C/C++語(yǔ)言編寫,那么可以將Lua與宿主源程序一同編譯,Lua與宿主合為一個(gè)整體。VB顯然不能采用這一方式。

        宿主程序也可以動(dòng)態(tài)鏈接Lua庫(kù)中的函數(shù)。在這種方式下Lua先獨(dú)立編譯為DLL文件,然后宿主程序在運(yùn)行時(shí)與Lua動(dòng)態(tài)鏈接。VB以下面的格式使用DLL中的API:

        Declare function函數(shù)名稱libs“動(dòng)態(tài)鏈接庫(kù)文件路徑”alias“庫(kù)函數(shù)名”(參數(shù)列表)as返回類型

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

        (1)VB使用的模塊文件

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

        以下是模塊文件Mudule1.bas應(yīng)該包含的內(nèi)容:

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

        該Win32 API用于后面的lua_tostring函數(shù)。

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

        #define LUA_GLOBALSINDEX(-10002)

        在VB中轉(zhuǎn)換為:

        Public Const LUA_GLOBALSINDEX As Long=(-10002)

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

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

        LUALIB_API void(luaL_openlibs)(lua_State*L);

        在VB中轉(zhuǎn)換為:

        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,參照上述方式進(jìn)行定義。注意函數(shù)返回類型除了lua_tonumber為Double外,其余均為L(zhǎng)ong;參數(shù)類型除了const char*應(yīng)定義為String外,其余均定義為L(zhǎng)ong;參數(shù)調(diào)用方式為ByVal按值調(diào)用。

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

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

        這些API在Lua.dll中無(wú)導(dǎo)出函數(shù),VB需用函數(shù)來(lái)實(shí)現(xiàn):

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

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

        參照以上方法用VB對(duì) lua_setglobal、lua_pushcfunction、lua_pop編寫相應(yīng)函數(shù)。而lua_tostring處理相對(duì)較多,對(duì)應(yīng)VB函數(shù)如下:

        在lauxlib.h中還有一個(gè)要用的API,對(duì)應(yīng)VB函數(shù)如下:

        (2)VB使用的類模塊

        Lua提供的API很多,對(duì)于宿主程序來(lái)說(shuō),未必會(huì)使用到全部的功能,最核心的無(wú)非是調(diào)用Lua函數(shù)、Lua調(diào)用宿主函數(shù)、運(yùn)行Lua語(yǔ)句塊、訪問Lua全局變量等交互。因此,為了方便進(jìn)行處理,我們可以建立以下類模塊。限于篇幅,類模塊將處理的數(shù)據(jù)類型縮減為數(shù)值、字符串和布爾三種常用類型,實(shí)際應(yīng)用時(shí)可根據(jù)需要進(jìn)行增加。

        下面是類模塊文件Class1.cls的主要內(nèi)容:

        Dim L As Long'Lua虛擬機(jī)指針

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

        Public Function LuaClose()As Long'關(guān)閉虛擬機(jī),代碼略

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

        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'返回棧頂內(nèi)容字串

        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'取變量?jī)?nèi)容,代碼略

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

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

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

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

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

        lua_getglobal L,fun

        A=Split(para,",")'參數(shù)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為結(jié)果個(gè)數(shù)

        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'注冊(cè)VB函數(shù),lp為VB函數(shù)指針

        lua_pushstring L,fun

        lua_pushcfunction L,lp

        LuaReg=lua_settable(L,LUA_GLOBALSINDEX)

        End Function

        (3)實(shí)例

        將Lua.dll復(fù)制到System32目錄中,新建工程“標(biāo)準(zhǔn)EXE”,導(dǎo)入模塊Mudule1.bas和類模塊Class1.cls(命名為L(zhǎng)uaClass),就可以在VB程序中使用Lua了。如在窗體Form1中,新建一個(gè)按鈕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

        新建一個(gè)模塊,輸入以下代碼:

        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

        運(yùn)行并點(diǎn)擊Command1,可得到運(yùn)行結(jié)果。

        3 封裝Lua到COM

        ASP、WSH、VBS等腳本語(yǔ)言不能直接使用DLL,我們可以將上述模塊封裝為COM組件,那么這些高級(jí)語(yǔ)言就可以通過(guò)COM使用Lua來(lái)進(jìn)行擴(kuò)展了。

        在VB中新建工程“ActiveX DLL”,導(dǎo)入模塊Mud-ule1.bas和類模塊Class1.cls(命名為L(zhǎng)uaClass),在菜單“工程”-“屬性”處,更改工程名為“Lua”,點(diǎn)擊“文件”-“生成dll”。假設(shè)生成c:LuaX.dll,運(yùn)行regsvr32 c:luaX. dll,復(fù)制Lua.dl1到System32中,然后上述腳本語(yǔ)言就可以通過(guò)COM使用Lua了。如建立并運(yùn)行如下腳本文件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 結(jié)語(yǔ)

        在國(guó)外TIOBE軟件廠商發(fā)布2014年7月份編程語(yǔ)言排行榜中,VB由2013年的第7位升高到第5位,占4.341%;而Lua排名36位,占0.332%。這說(shuō)明即使在Microsoft轉(zhuǎn)向.NET平臺(tái)多年以后,VB依然受到編程者的喜愛,而Lua的發(fā)展?jié)摿艽?。在VB中調(diào)用Lua,結(jié)合VB的快速開發(fā)特性和Lua的靈活性,我們開發(fā)的應(yīng)用將更有彈性,而對(duì)于Lua接口API的再封裝,無(wú)疑為ASP等腳本語(yǔ)言使用Lua打開了一扇大門。

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

        [2]鄧正陽(yáng),陳和平,蘇鵬.動(dòng)態(tài)腳本語(yǔ)言Lua與C++交互方法的研究與實(shí)現(xiàn)[J].計(jì)算機(jī)系統(tǒng)應(yīng)用,2010,19(5):198-201.

        [3]魏江平.LUA腳本語(yǔ)言在游戲引擎中的應(yīng)用分析[J].微型電腦應(yīng)用,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]張帆.可重構(gòu)軟件平臺(tái)構(gòu)建原理與應(yīng)用研究[D].武漢理工大學(xué),2012.

        [6]鄧楠喬,秦開宇,金燕華.基于Lua的面向組件程序設(shè)計(jì)研究[J].中國(guó)高新技術(shù)企業(yè),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腳本技術(shù)的網(wǎng)絡(luò)化測(cè)控系統(tǒng)設(shè)計(jì)[J].西安郵電大學(xué)學(xué)報(bào),2013,18(1):90-94.

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

        [10]孫秀梅,鞏建華.Visual Basic開發(fā)實(shí)戰(zhàn)1200例(第1卷)[M].北京:清華大學(xué)出版社,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-),男,廣西桂林人,講師,碩士,研究方向?yàn)橛?jì)算機(jī)程序設(shè)計(jì)、遠(yuǎn)程教育技術(shù)

        2015-09-15

        2015-09-30

        VB和Lua都是常用的編程語(yǔ)言,為了結(jié)合利用VB和Lua各自的優(yōu)點(diǎn),快速、高效、靈活地進(jìn)行應(yīng)用程序開發(fā),通過(guò)對(duì)C與Lua之間交互模式的研究分析,提出VB與Lua交互調(diào)用的方法,并進(jìn)一步將VB調(diào)用Lua的接口封裝為COM組件,以隱藏細(xì)節(jié)信息和簡(jiǎn)化調(diào)用接口,可支持更多其他編程語(yǔ)言如ASP、VBS等調(diào)用Lua。實(shí)踐證明,這種VB 與Lua的交互調(diào)用方式是有效的、易于使用的。

        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.

        猜你喜歡
        定義
        以愛之名,定義成長(zhǎng)
        活用定義巧解統(tǒng)計(jì)概率解答題
        例談橢圓的定義及其應(yīng)用
        題在書外 根在書中——圓錐曲線第三定義在教材和高考中的滲透
        永遠(yuǎn)不要用“起點(diǎn)”定義自己
        海峽姐妹(2020年9期)2021-01-04 01:35:44
        嚴(yán)昊:不定義終點(diǎn) 一直在路上
        定義“風(fēng)格”
        成功的定義
        山東青年(2016年1期)2016-02-28 14:25:25
        有壹手——重新定義快修連鎖
        修辭學(xué)的重大定義
        亚洲一区二区三区免费av在线| 国产又黄又爽又色的免费| 日本三级欧美三级人妇视频| 久久精品国产6699国产精| 亚洲码无人客一区二区三区| 白嫩人妻少妇偷人精品| 伊人激情av一区二区三区| 国产午夜精品电影久久| 国产精品亚洲一区二区三区正片| 亚洲美女自拍偷拍视频| 中国丰满人妻videoshd| 国产成人国产在线观看入口| 日韩少妇人妻一区二区| 国产av一区二区三区在线播放| 人人妻人人爽人人澡欧美一区 | 国产色噜噜| 亚洲av中文字字幕乱码| 亚洲在线视频免费视频| 日本免费a级毛一片| 久久88综合| 日韩女同一区二区三区久久| 日韩精品人妻久久久一二三| 中文字幕一区二区三区人妻少妇| 久久国产精品视频影院| 清纯唯美亚洲经典中文字幕| 夜夜夜夜曰天天天天拍国产| 丰满女人又爽又紧又丰满| 人妻中文字幕不卡精品| 福利利视频在线观看免费| 一本色道久久综合无码人妻| 69av视频在线观看| 国产一区二区三区porn| 亚洲午夜久久久精品影院| 国产96在线 | 欧美| 麻豆国产成人AV网| 国内偷拍国内精品多白86| 狠狠噜天天噜日日噜无码| 国产97色在线 | 免| 亚洲一二三四五中文字幕| 朝鲜女人大白屁股ass孕交| 欧美丰满熟妇bbbbbb百度 |