<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                [TOC] ## 概述 最近在學習 云風的`skynet`庫,想自定義一個模塊,目標是使用lua調用C/C++所編寫的庫。 當我們需要在`Lua`里面調用`c/c++`函數時,所有的函數都必須滿足以下函數簽名: ```cpp typedef int (*lua_CFunction) (lua_State *L); ``` 換句話說,所有的函數必須接收一個lua\_State作為參數,同時返回一個整數值。因為這個函數使用Lua棧作為參數,所以它可以從棧里面讀取任意數量和任意類型的參數。而這個函數的返回值則表示函數返回時有多少返回值被壓入Lua棧。(因為Lua的函數是可以返回多個值的)。 ## lua調用C/C++的動態庫 lua調用C動態庫有如下幾個步驟: 1. 寫C動態庫 2. lua調用C動態庫 C動態庫的重要部分 :定義一個 luaopen_* 函數,并調用 `luaL_newlib` 函數,這個函數相當于作為此動態庫的main函數。需要注意: * `luaopen_`是此函數的前綴,不可修改。后面的內容是我們在lua中使用 require 引用此庫時的字符串名稱(假如名稱中帶有下劃線,在使用require需要將下劃線替換為點,例如:“mylib_test”->“mylib.test”)。 * 在Lua5.0中調用的是`luaL_openlib`,但是在Lua5.3中,則是使用`luaL_newlib` ### 示例 看一個示例: ``` //snpccfg.cc #ifdef __cplusplus extern "C" { #endif #include "lua.h" #include "lauxlib.h" #include "lualib.h" #ifdef __cplusplus } #endif #include <stdio.h> static int test(lua_State *L) { size_t len = 0; int num = luaL_checkinteger(L, 1); const char* str = luaL_checklstring(L, 2, &len); printf("come from test: num = %d,str = %s,len = %d\n", num, str, len); return 0; } extern "C" int luaopen_snpccfg(lua_State *L) { luaL_Reg l[] = { {"test",test}, // key-val,相當于{"(lua調用時使用的函數名)",C定義函數名(函數指針)} {NULL,NULL} // 必不可少 }; luaL_checkversion(L); luaL_newlib(L,l); return 1; } ``` `luaL_checkinteger()` 和?`luaL_checklstring()`是用來獲取參數的。 生成動態庫: ``` gcc -fPIC -shared -o snpccfg.so snpccfg.cc -I./lua -L./lua -llua ``` >需要通過-I和-L指定lua頭文件和liblua.a庫的路徑 ``` --test.lua package.cpath = "./?.so" --庫路徑 local snpccfg = require "snpccfg" snpccfg.test(1, "12312") ``` 執行腳本 ``` $ lua test.lua come from test: num = 1 str = 12312 len = 5 ``` ### 遇到的問題 1.relocation R_X86_64_32S against `luaT_typenames_' can not be used when making a shared object; recompile with -fPIC 解決辦法: 重新編譯liblua.a庫,Makefile:CFLAGS=加上-fPIC ,而后再編譯安裝 ``` make linux make install ``` ### 需要注意的幾個點 1. 在C++中編譯成動態庫,需要在函數 `luaopen_snpccfg`前面增加 extern "C",否則在使用該動態庫時會有如下錯誤: ``` lua: error loading module 'snpccfg' from file './snpccfg.so': ./snpccfg.so: undefined symbol: luaopen_snpccfg stack traceback: [C]: in ? [C]: in function 'require' test.lua:2: in main chunk [C]: in ``` 2. 在C中則使用extern來修飾函數`luaopen_snpccfg`, 引用書中的話: * `extern`是計算機語言中的一個關鍵字,可置于變量或者函數前,以表示變量或者函數的定義在別的文件中。提示編譯器遇到此變量或函數時,在其它模塊中尋找其定義,另外,extern也可用來進行鏈接指定。 * extern 后面修飾的只能是一個全局變量。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看