是否可以通过函数地址从 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++ 函数?的主要内容,如果未能解决你的问题,请参考以下文章

Redis:ioredis 与 lua 脚本

Lua, Require, 可用函数

在JAVA中使用LUA脚本记,javaj调用lua脚本的函数(转)

Lua脚本语言——进阶语法

lua 与 c++或者c 交互的底层原理谁能解释一下?最最底层的,为啥它们调用C或者C++的函数?

是否可以调用任何网页的Java脚本功能?