1

我已经编译了用 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;
}

任何想法如何在编译的主机程序中使用它?

4

2 回答 2

3

从 Lua 调用 C/C++ 函数的正确方法是编写接口代码以在 Lua 堆栈上交换数据。

但是,有一些扩展允许直接调用共享库(.dll 或 .so)中的函数。

查看使用 libffi 库 ( http://www.sourceware.org )的 FFI 库 ( http://luajit.org/ext_ffi.html ) 或 Alien Lua ( http://alien.luaforge.net/ ) /libffi/ )

于 2014-02-14T10:55:06.940 回答
1

要在 Lua 中访问 C/C++ 函数,您必须通过某个 api 公开它们,Lua 不会直接加载“常规”dll(或者 .so,如果你这样做的话)。相反,您必须有一个中间库来向 Lua 环境公开哪些 C 函数可用。

干杯

于 2014-02-14T10:35:30.447 回答