c++ - 是否可以通过函数地址从 lua 脚本调用任何主机 c/c++ 函数?

标签 c++ c lua language-interoperability

我已经编译了用 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调用C/C++函数的正确方法是编写接口(interface)代码,在Lua栈上交换数据。

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

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

关于c++ - 是否可以通过函数地址从 lua 脚本调用任何主机 c/c++ 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21776901/

相关文章:

javascript - emscripten_run_script() 在优化构建中被移除

c++ - 我的 do while 循环只执行一次

c - 链表最合适的替代方案是什么?

c - 需要 MSVCR120.DLL

postgresql - 删除记录时锁定数据库表 - 了解 postgresql 中的 "Read Committed"事务隔离

performance - 在循环内部或外部声明局部更好吗?

c - Lua - lua_tostring() 返回奇怪的结果

c++ - JCuda全局共享内存导致错误

c++ - 我应该在 C++ 中使用内存地址作为应用程序级标识符吗?

c - 为什么1的补码是-2