程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> LUACOM-IDL-VBS

LUACOM-IDL-VBS

編輯:C++入門知識

 LUA很好用,在Windows下COM是老大,如果能結合它們的功能,那會是比較酷的。LuaCOM庫(目前版本1.4)非常好的扮演了這個牽線搭橋的角色,本文不討論Luacom的各項功能,大家可下載LuaCOM User Manual手冊作全面的了解。這面只是舉一個HelloWorld的例子,以及在實現這個例子過程的一點教訓。網上關於這方面的詳細例子不多(也可能是本人的搜索方法不是很對),基本上找不著HellowWorld檔次的例子,所以感覺有必要寫一個博客,與有興趣的讀者共享,也做為自己的筆記。     說廢話一向不是本人的風格,現在就開始。     准備必要的工具,如果有安裝了VS IDE那是最好的,除了MIDL.exe之外還有Visual Studio Command Prompt (2010)都可以輕松獲得。再就是Lua.exe和LuaCOM.dll,這裡有個教訓就是Lua.exe和LuaCOM.dll的版本要相適應(LuaCOM.dll最好是1.4版本的,1.3好像測試無法正常通過,也沒仔細去研究,用上1.4的就正常了,如果大家能在1.3下通過下邊這個例子,請給個跟貼,謝謝)。     准備一個idl文件,然後使用MIDL.exe生成一個tlb文件,文件名分別為test.idl和test.tlb。 test.idl [cpp]   //VBScript and JScript do not support [in,out], use [in,out] or [out,retval]    //import "unknwn.idl";      [       uuid(991AB5E0-97C4-4ecc-9926-D76038C517A1),       version(1.0)   ]   library TEST   {       importlib("STDOLE2.TLB");              [           object,           uuid(1AB5DCC7-11F7-441f-962C-57A528F85F47),           dual,           oleautomation,           version(1.0),           helpstring("luacom interface implement test 1.0")       ]       interface ITest : IDispatch {            void Version([in,out]short* major, [in,out]short* minor);       };          [uuid(340DFD25-59B2-49b4-A693-A7B19A13FD42)]       coclass Test {           [default] dispinterface ITest;       }   };       本人不熟悉VBScript和JScript,一開始參數只是指定[out],結果一定得不到正常的返回結果(沒有返回結果),在網上搜了搜才知道不支持[out]參數,如果在LuaCOM,這樣的參數是能正常返回的。     准備一個實現COM的Lua腳本,在LuaCOM手冊上有一個,在這裡只是稍做改動,以實現上面的ITest接口。 testobj.lua [cpp]   --This is the implementation of the COM object   local LOON_DIR = os.getenv("loon");   package.cpath = LOON_DIR .. [[\..\lua\?.dll]]   require "luacom"   path_to_script = LOON_DIR .. [[\..\lua\idl\]]      ------------------------------------------------------------------------------      TestObj = {}   function TestObj:Version(a,b)       return 123+a,455+b;   end      ------------------------------------------------------------------------------   COM = {}      function COM:StartAutomation()       --print("testobj.lua > StartAutomation");       -- Creates the object using its default interface       COMAppObject, events, e = luacom.NewObject(TestObj, "TEST.Test");       --print("testobj.lua > " .. tostring(COMAppObject), events, e);       -- This error will be caught by detectAutomation       if COMAppObject == nil then           error("NewObject failed: " .. e);       end       -- Exposes the object       cookie = luacom.ExposeObject(COMAppObject);       if cookie == nil then           error("ExposeObject failed");       end       --print("testobj.lua > ookie=" .. tostring(cookie));   end      function COM:Register()       -- Fills table with registration information       local reginfo = {};       reginfo.VersionIndependentProgID = "TEST.Test";       reginfo.ProgID = reginfo.VersionIndependentProgID .. ".1";       reginfo.TypeLib = "test.tlb";       reginfo.CoClass = "Test";       reginfo.ComponentName = "Test Component use luacom";       reginfo.Arguments = "/Automation";       reginfo.ScriptFile = path_to_script .. "testobj.lua";       -- Stores compnent information in the registry       local res = luacom.RegisterObject(reginfo);       if res == nil then           error("RegisterObject failed!");       end   end      function COM:UnRegister()       -- Fills table with registration information       local reginfo = {};       reginfo.VersionIndependentProgID = "Test.Test";       reginfo.ProgID = reginfo.VersionIndependentProgID .. ".1";       reginfo.TypeLib = "test.tlb";       reginfo.CoClass = "Test";       -- removes compnent information from the registry       local res = luacom.UnRegisterObject(reginfo);       if res == nil then           error ("UnRegisterObject failed!");       end   end      -- starts automation server   return luacom.DetectAutomation(COM);   --xCom = { luacom.DetectAutomation(COM); };   --for k,v in pairs(xCom) do       --print(k,v);   --end   --return unpack(xCom);         執行2個命名,一個是生成test.tlb,另一個是將COM注冊到注冊表中,執行完後,大家可到注冊表中去看看它的注冊內容 maketlb.bat [html]  @REM SET MIDLDir="c:\Program Files\Microsoft SDKs\Windows\v7.0A\bin"   SET MIDLDir="d:\Program Files\Microsoft SDKs\Windows\v6.0A\bin"   SET IDLFile="%loon%\..\lua\idl\test.idl"   SET TLBFile="%loon%\..\lua\idl\test.tlb"      @SET PATH="%loon%\..\lua\";%PATH%   chdir /d %MIDLDir%   midl.exe "%IDLFile%" /tlb "%TLBFile%" /out "%loon%\..\lua\"      chdir /d "%loon%\..\lua\idl"   lua testobj.lua /register       實現(純Lua代碼)和注冊已經完成,下面就可以使用這個COM接口了。這裡分別是用LuaCOM腳本和VBS腳本來調用它。 test.lua [cpp]   package.cpath = os.getenv("loon") .. [[\..\lua\?.dll]]   require "luacom"      obj = {};   print("testlua.lua > luacom=" .. tostring(luacom));   x = luacom.CreateObject("TEST.Test");   print("testlua.lua > comobj=" .. tostring(x));   for k,v in pairs(x) do  www.2cto.com     print(k,v);   end   print(x:Version(4,5));   test.vbs [cpp]   ON ERROR RESUME NEXT   Set x = CreateObject("TEST.Test")   Dim a,b   a=4   b=5   x.Version a,b   MsgBox "Version: "+CStr(a)+"."+CStr(b), vbOK          可以看到輸出結果 127和460,說明輸進去的接收到了,修改後返回也正確接收到了。  

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved