lua中調用C++函數
我們產品中提供了很多lua-C API給用戶在lua中調用,之前一直沒用深究其實現原理,只是根據已有的代碼在編碼。顯然這不是一個好的習慣,沒用達到知其所以然的目的。
一、基本原理
將C++函數編譯成動態鏈接庫,然后在lua中require,通過下面的示例進行詳解。
#ifdef __cplusplus
extern "C" {
#endif
#include<lua.h>
#include<lualib.h>
#include<lauxlib.h>
#ifdef __cplusplus
}
#endif
static int add (lua_State *L)
#ifdef __cplusplus
extern "C" {
#endif
#include<lua.h>
#include<lualib.h>
#include<lauxlib.h>
#ifdef __cplusplus
}
#endif
/**
要寫一個lua中可以調用的函數,一般需要三個步驟,
第一步:定義函數,而且要遵守一定的規則,即
參數只能有一個(lua_State*),返回值也只能為
整型int,本例中static關鍵字可以不寫。
*/
static int add (lua_State *L)
{
double op1 = lua_tonumber(L, -1);
double op2 = lua_tonumber(L, -2);
lua_pushnumber(L, op1+op2);
return 1;
}
/**
第二步:列出所有的本模塊中供lua調用的函數,為下
面的注冊做准備
*/
static luaL_Reg myfuncs[] = {
{"add", add},
{NULL, NULL}
};
/**
第三步:注冊函數到一個lua table中去。
*/
extern "C" int luaopen_mytestlib(lua_State *L)
{
luaL_register(L, "mytestlib", myfuncs);
return 1;
}
二、編譯
$ g++ lua_call_cplusplus_function.cc -o mytestlib.so -shared -fPIC -I /usr/include/lua5.1/
三、運行結果
$ lua
Lua 5.1.5 Copyright (C) 1994-2012 Lua.org, PUC-Rio
> require("mytestlib")
> print(mytestlib.add(1,2))
3
四、注意事項
- luaL_register在lua5.2中被移除了,如果使用lua5.3編譯會報如下錯誤
$ g++ mytestlib.cc -o test.so -shared -fPIC -I /home/wuman/下載/lua-5.3.2/src
mytestlib.cc: In function ‘int luaopen_test(lua_State*)’:
mytestlib.cc:21:34: error: ‘luaL_register’ was not declared in this scope
luaL_register(L, "test", testlib);
- luaopen_mytestlib這個 extern "C"是必須的,否則require時會報錯:
$ lua
Lua 5.1.5 Copyright (C) 1994-2012 Lua.org, PUC-Rio
> require("mytestlib")
error loading module 'mytestlib' from file './mytestlib.so':
./mytestlib.so: undefined symbol: luaopen_mytestlib
stack traceback:
[C]: ?
[C]: in function 'require'
stdin:1: in main chunk
[C]: ?
