[英]How do I call C++ functions from a Lua script?
我正在使用Visual Studio 2005。
------------------------ [luapassing.cpp] --------------------
#include "lua.h"
static int myCfunc (Lua_State *L){
double trouble = lua_tonumber(L,1);
lua_pushnumber(L,16.0 -trouble);
return 1;
}
int luaopen_luapassing (Lua_State *L){
static const lua_reg Map [] = {{"dothis",myCfunc},{NULL,NULL}};
luaL_register(L,"cstuff",Map);
return;
}
------------------------- [csample.lua] -------------------- -----
package.cpath = "./CLua2.dll"
require "luapassing"
print("hola")
print(seth.doThis(120))
我看到几个问题。 我将对其进行描述,并提供一个代码片段,该片段应该可以正常运行,因为我相信您希望此示例正常工作。
您的第一个问题是C ++编译器修改了从DLL导出的唯一对Lua至关重要的函数的名称: luaopen_luapassing()
。 Windows的常规二进制发行版被编译为C程序,并且为DLL模块入口点采用C样式名称。
另外,您对luaopen_x
函数的协议略有错误。 该函数返回一个整数,该整数告诉Lua Lua堆栈顶部的多少项是Lua使用的返回值。 require
假设的协议希望您将新模块的表对象放在堆栈顶部,然后将其返回给Lua。 为此, luaopen_x
函数通常会像您一样使用luaL_register()
,然后返回1。
还有命名的问题。 用纯Lua编写的模块有机会减少对其名称的了解。 但是用C编写的模块必须从DLL中导出一个函数,该函数的名称中应包含模块名称。 他们还必须向luaL_register()
提供该模块名称,以便在全局环境中创建和更新正确的表。 最后,客户端Lua脚本将在全局表中看到已加载的模块,该全局表的名称类似于传递给require
的名称,该表也从require
返回,以便可以将其缓存在该脚本的本地中。
使用C代码的其他一些lua_Number
是,为了可移植性,应该将数字类型实际上拼写为lua_Number
,并且通常使用luaL_checknumber()
而不是luaL_checknumber()
lua_tonumber()
来强制执行该函数所需的参数。 就个人而言,我会用与Lua公开知道的名称相关的名称来命名公共函数的C实现。但这只是一个问题。
C端的此版本应解决以下问题:
#include "lua.h"
static int my_dothis (Lua_State *L){
lua_Number trouble = luaL_checknumber(L,1);
lua_pushnumber(L,16.0 -trouble);
return 1;
}
extern "C" int luaopen_luapassing (Lua_State *L){
static const lua_reg Map [] = {
{"dothis", my_dothis},
{NULL,NULL}
};
luaL_register(L,"luapassing",Map);
return 1;
}
然后,示例脚本需要使用其专有名称引用加载的模块,并通过其专有名称引用该模块定义的功能。 Lua区分大小写,因此,如果模块创建名为dothis()
的函数,则脚本必须使用相同的名称,例如,找不到名为doThis()
的函数。
require "luapassing" print("hola") print(luapassing.dothis(120))
我应该补充一点,我实际上还没有编译并运行上面的代码,因此练习中可能还剩下一两个错字;-)
如果要进行很多C ++到lua的绑定,则可能需要看看luabind 。
如果您使用C ++进行编译并希望匹配“ C”接口,则应将外部可见函数声明为extern "C"
以避免名称修改。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.