Lua调用只有头文件的C++动态库函数
来源:互联网 发布:python字符串转字典 编辑:程序博客网 时间:2024/04/27 22:35
前段时间公司让我寻找一个for C++的Lua Binder库,要求C++ 和 Lua能够双向调用(所以SWIG/tolua排除),最后选择了LuaBind的一个fork,名叫LuaPonte,选择的原因是既有LuaBind的广泛使用比较可靠,又支持LuaJIT(我们要用)的5.1语法。
昨天做summary presentation时我用这个例子展示Lua调C++的效果
void print_hello(int number) { std::cout << "hello world " << number << std::endl;}int main() { // Create a new lua state lua_State *myLuaState = luaL_newstate(); // Connect LuaBind to this lua state luabind::open(myLuaState); // Add our function to the state's global scope luabind::module(myLuaState) [ luabind::def("print_hello", print_hello) ]; // Now call our function in a lua script luaL_dostring( myLuaState, "print_hello(123)\n" ); lua_close(myLuaState);}
没想到被人challenge了,说print_hello函数是自己定义的,实际项目中很可能不知道函数的定义,这时你怎么保证还能调用?
当时没反应过来,我选的LuaPonte也被architect枪毙掉了。。。。。。
今天仔细了解了下Lua调C的方法,总结起来就是
1,假设你的库里有n个函数,库名libxxx.so,则必须提供一个函数
2,在luaopen_xxx里调用luaL_Register注册你的所有n个函数
3,其中每个函数都必须是lua_CFunction类型
4,每个lua_CFunction获取Lua通过栈传入的参数,计算后将结果通过栈传回Lua
网上给的很多lua_CFunction示例,基本都是这样
int myAdd(lua_State *L){int a = lua_getinteger(L, 1);// 1st argint b = lua_getinteger(L, 2);// 2nd arglua_pushinteger(L, a+b); //return sum to luareturn 1; // return result num}
int myAdd(lua_State *L){//根据类型推导库(boost::any等)获得参数个数和类型,略int arg1 = lua_getinteger(L, 1);// 1st argint arg2 = lua_getinteger(L, 2);// 2nd argint result1 = trueAdd(arg1, arg2); //the wrapped func!lua_pushinteger(L, result1); //return sum to luareturn 1; // return result num}
这样就将负责bind的myAdd和负责运算的trueAdd分离开来。
其实这个trueAdd完全可以放在第三方库里,由LuaPonte(或其他Binder库)根据trueAdd的签名(头文件)生成myAdd,然后主程序链接myAdd,myAdd又链接trueAdd。
估计SWIG也是这么个路子,只是SWIG要额外产生一个so,相比之下该方法更好。
最后上一个自己写的例子
test.cpp
#include <luaponte/luaponte.hpp>extern int myAdd(int a, int b);//all from third party lib's header fileint main(){ // Create a new lua state lua_State *myLuaState = lua_open(); // Connect LuaBind to this lua state luaponte::open(myLuaState); luaponte::module(myLuaState)[ luaponte::def("myAdd", myAdd) ]; std::cout << "Result: " << luaponte::call_function<int>(myLuaState, "myAdd", 2, 3) << std::endl; lua_close(myLuaState); return 0;}
libtest.cpp
int myAdd(int a, int b){ return a+b;}
Makefile
all: g++ -fPIC -c libtest.cpp -o libtest.o g++ -shared -o libtest.so libtest.o -ldl g++ -std=c++11 -c test.cpp -o test.o -I/root/pkgs/luaponte-master/ g++ -o test -L/usr/local/lib -L/root/pkgs/luaponte-master/build/src/ -L. test.o -ltest -lluaponte -lluaclean: rm -f *.o *.so test
注意:若运行报找不到libtest.so,一般是LD_LIBRARY_PATH没有加入当前目录,加入即可。
1 0
- Lua调用只有头文件的C++动态库函数
- 标准库函数的头文件
- Java调用C/C++生成的动态库函数
- C语言 调用的动态库函数重名问题分析
- 标准C/C++库函数头文件
- C语言常用头文件及库函数
- C语言头文件的调用过程
- 【Lua】Lua调用C动态库
- 文件操作:系统调用和C库函数的区别
- 在C中调用C++动态库函数
- 调用C语言的库函数
- C/C++的库函数调用
- 关于头文件,库函数,静态库,动态库,的一系列迷惑... (转)
- C++标准库函数的头文件收集
- 头文件和库函数的区别
- linux 查找系统调用和库函数头文件
- 一些常用C库函数所属的头文件,列出来用的时候查的方便
- C++库函数头文件
- 安卓的第一份实验单【2014年10月15日布置,11月11日上交】
- String to Integer (atoi) (Java)
- Spring3.x中的分布式事务配置
- 23个经典营销创业案例,彻底颠覆你的营销思维
- Spark是什么,如何使用Spark(之一)
- Lua调用只有头文件的C++动态库函数
- java socket编程
- javascript DOM
- 2014-10-15工作
- 安卓第二课:教材中游戏启动界面实现之准备知识
- HTML5 标签列表
- 黑马程序员——面向对象11:组合
- UVA537
- 【Android JNI】JNIEnv和JavaVM的区别