Lua指令碼調用C++動態庫

來源:互聯網
上載者:User

前言:又是N久沒上來了,也沒什麼新鮮話想說。反正最近是被杭州的樓價憋得抑鬱,但是也是只能對自己說要“蛋腚”!今天又被這個lua調用DLL給抑鬱了一把,還好網上搜來搜去,終於搜到一位“有識之士”的文章,幫我搞定了這個“憋屈”的問題。最近很懶,懶得寫東西。

 

  Lua調用C的DLL的例子網上也不是很多,其實要說很多的話,轉帖是大部分的形式,有好有壞吧。轉得多了,倒是讓人看得鬱悶,因為搜了半天都是一樣的東西,甚至沒有自己想要的,好處也有,有需要的人,隨便一搜就搜到了,頓時心情不錯,對社會的“憤青”又少了幾個。因為真的很難找到,所以,我還是做做好人把東西這裡發一下,順便修修補補幾下。

  先來看一段dll的cpp吧,沒啥東西,就是個demo:

// LuaCall.cpp : Defines the entry point for the DLL application.<br />//<br />#include "LuaCall.h"<br />#define PAS(L, n) (lua_tostring(L, n))<br />int lua_helloLua(lua_State* L)<br />{<br />printf("Hello Lua, I'm in Cpp! Lua's message is: %s/n", PAS(L, 1));<br />return 0;<br />}<br />luaL_reg gtfunc[] =<br />{<br />{"hellolua", lua_helloLua},<br />{NULL, NULL}<br />};<br />extern "C" int luaopen_luacall(lua_State* L)<br />{<br />luaL_register(L, "gt_lib", gtfunc);<br />return 1;<br />} 

  我再多費唇舌幾下:lua調用C/C++的函數有個基本規則,該函數必須要是lua_Cfunction的格式(不知道自己查去,或者看例子中的lua_helloLua也行,反正就是這個格式)。幾個比較關鍵的地方就是入口函數和庫函數了(假使你寫的是個小工具庫,那麼如同lua_helloLua一樣,這個就算是個庫函數)。例子中的入口函數為luaopen_luacall,也需要是lua_Cfunciton格式的,因為這個入口函數在lua調用的時候需要執行。另一個就是存放庫函數的結構luaL_reg結構。最後一個關鍵的地方就是把庫函數註冊到lua環境中去,用的就是luaL_register函數。這些函數的用法可以去http://www.lua.org/manual/5.1/自己查詢一下,我就不贅述了。

  這裡的gtfunc是個luaL_reg結構的數組,需要以一個雙NULL的結構作為結束標誌,其他的也沒啥值得注意的地方。

  C和C++由於編譯不一樣,因為lua是用C寫的,所以在C++匯出函數,要用 extern "C" 修飾,下面luaCall.h匯入lua的標頭檔也一樣:

extern "C" {<br />#include "lua.h"<br />#include "lualib.h"<br />#include "lauxlib.h"<br />}<br /> 

 

  def檔案中寫上匯出函數的名字

  EXPORTS

luaopen_luacall

  就可以了。

 

  下面講最抑鬱的地方,一定要注意,在windows下測試中發現的問題,我相信在linux下也差不多,不過我沒去驗證過。

  lua調用DLL的入口函數一定是要命名成luaopen_xxx的(這個可以參考lua.org上的文檔),並且,如果使用require方式,那這個XXX一定要是這個dll的名稱,在lua指令碼中require時大小寫敏感。也就是說,例子中,dll檔案必須命名為luacall.dll,注意大小寫。

  如果是用package.loadlib方式,那麼匯入的dll檔案名稱可以不同。個人看來是require比較懶惰啦,呵呵。

  下面是lua中調用的demo,這裡示範了dll檔案名稱在package.loadlib中可以不同於匯出函式宣告:

local f = package.loadlib("luacalls.dll", "luaopen_luacall");<br />-- require("luacall")<br />f();<br />for k, v in pairs(gt_lib) do<br />print(k, v);<br />end<br />if gt_lib then<br />gt_lib.hellolua("hahaha");<br />print(gt_lib.add(1, 5));<br />end<br /> 

  調用dll有兩種方式,一種是require,一種是package.loadlib,區別是,require是預設去調用下入口函數的,而package.loadlib只是載入,需要你手動調用。

  demo中,就是預設package.loadlib的形式,下面需要顯示得執行以下f(),表示調用載入的庫,而如果是用require的話,直接就可以從if gt_lib then這句開始了。

  最後嘮叨句,如果是用luaL_reg數組的形式,那麼註冊到lua中的是一個table,如果是單個結構,那麼就是函數,還有就是注意lua51.dll的位置,最保險就是講幾個dll和指令碼呢統統放到同一個目錄下執行。自己動手試一下吧,呵呵。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.