是否可以通过函数地址从 lua 脚本调用任何主机 c/c++ 函数?
Posted
技术标签:
【中文标题】是否可以通过函数地址从 lua 脚本调用任何主机 c/c++ 函数?【英文标题】:is it possible to call any host c/c++ function from lua script by function address? 【发布时间】:2014-02-14 10:32:08 【问题描述】:我已经编译了用 c/c++ 编写的控制台主机程序(我没有源代码)。宿主程序支持 lua 脚本(可能使用 lua 虚拟机)。宿主程序加载lua库
luaopen_base luaopen_table luaopen_string luaopen_math luaopen_debug
并允许重新加载所有 lua 脚本。
是否可以通过函数地址从 lua 脚本调用任何宿主 c/c++ 函数(从宿主程序中的外部调试器获取它们)?
在这种情况下是否可以从 lua 加载任何 C/C++ 编译的库并调用其函数?
其他论坛上的一个人为这个问题写了这段代码
// re = callClientFunction(addr, args , 'cdecl')
// re = callClientFunction(method, obj, arg1 , 'this')
// re = callClientFunction(0x08, obj, arg1 , 'this') = obj->vtable[2]->(arg1)
inline int callCdeclFunction(lua::State* L, uintptr_t addr, const std::vector<lua::Integer>& args)
typedef lua::Integer __cdecl cf0();
typedef lua::Integer __cdecl cf1(lua::Integer);
typedef lua::Integer __cdecl cf2(lua::Integer, lua::Integer);
typedef lua::Integer __cdecl cf3(lua::Integer, lua::Integer, lua::Integer);
typedef lua::Integer __cdecl cf4(lua::Integer, lua::Integer, lua::Integer, lua::Integer);
typedef lua::Integer __cdecl cf5(lua::Integer, lua::Integer, lua::Integer, lua::Integer, lua::Integer);
lua::Integer re = 0;
switch(args.size())
case 0: re = reinterpret_cast<cf0*>(addr)(); break;
case 1: re = reinterpret_cast<cf1*>(addr)(args[0]); break;
case 2: re = reinterpret_cast<cf2*>(addr)(args[0], args[1]); break;
case 3: re = reinterpret_cast<cf3*>(addr)(args[0], args[1], args[2]); break;
case 4: re = reinterpret_cast<cf4*>(addr)(args[0], args[1], args[2], args[3]); break;
case 5: re = reinterpret_cast<cf5*>(addr)(args[0], args[1], args[2], args[3], args[4]); break;
default:
luaL_error(L, "%s: too many args (max %d, provided %d).\n", __func__, 5, args.size());
return re;
任何想法如何在编译的主机程序中使用它?
【问题讨论】:
宿主程序是动态加载 Lua 还是静态链接 Lua?在第一种情况下,您可能可以编写自己的“Lua”库并欺骗主机。 【参考方案1】:从 Lua 调用 C/C++ 函数的正确方法是编写接口代码以在 Lua 堆栈上交换数据。
但是有一些扩展允许直接调用共享库(.dll 或 .so)中的函数。
查看 FFI 库 (http://luajit.org/ext_ffi.html) 或使用 libffi 库 (http://www.sourceware.org/libffi/) 的 Alien Lua (http://alien.luaforge.net/)
【讨论】:
“FFI 库”不是库;这是 LuaJIT 的一个特性。【参考方案2】:要在 Lua 中访问 C/C++ 函数,您必须通过某个 api 公开它们,Lua 不会直接加载“常规”dll(或 .so,如果你这样做的话)。相反,您必须有一个中间库来向 Lua 环境公开哪些 C 函数可用。
干杯
【讨论】:
以上是关于是否可以通过函数地址从 lua 脚本调用任何主机 c/c++ 函数?的主要内容,如果未能解决你的问题,请参考以下文章
在JAVA中使用LUA脚本记,javaj调用lua脚本的函数(转)