【问题标题】:is it possible to call any host c/c++ function from lua script by function address?是否可以通过函数地址从 lua 脚本调用任何主机 c/c++ 函数?
【发布时间】: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”库并欺骗主机。

标签: c++ c lua language-interoperability


【解决方案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 函数可用。

干杯

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-15
    • 2018-04-23
    • 2018-08-31
    • 2020-10-01
    • 2021-04-16
    • 2019-03-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多