我怎样从Lua脚本调用C++函数?

我正在使用 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))

原文链接 https://stackoverflow.com/questions/1209748

点赞
stackoverflow用户118959
stackoverflow用户118959

如果您正在编译为 C++ 并且想要匹配一个 'C' 接口,您应该将外部可见函数声明为 extern "C",以避免名称混淆。

2009-07-30 22:30:28
stackoverflow用户139091
stackoverflow用户139091

如果你要频繁进行 C++ 到 Lua 的绑定,你可能需要关注 luabind

2009-07-30 22:34:53
stackoverflow用户68204
stackoverflow用户68204

我发现了几个问题。我将描述这些问题,并提供一个代码片段,应该能够按照你打算的方式使这个示例运作。

你的第一个问题是,C++编译器弄乱了你的DLL中唯一一个对Lua来说重要的函数luaopen_luapassing()的名称。 Windows平台的标准二进制发行版是作为C程序编译的,并且假定DLL模块入口点使用C风格名称。

此外,luaopen_x函数的协议有些不对。该函数返回一个整数,告诉Lua堆栈顶部有多少个返回值供Lua使用。require函数认为返回新模块对象的表并把它留在堆栈的顶部会更好。为了做到这一点,luaopen_x函数通常会使用luaL_register(),然后返回1。

还有一个命名问题。纯Lua编写的模块有更少的命名意识。但是用C编写的模块必须从DLL中导出一个函数,该函数名称包括模块名称。它们还必须向luaL_register()提供该模块名称,以便在全局环境中创建和更新正确的表。最后,客户端Lua脚本将在名为require传递的名称的全局表中看到已加载的模块,该名称也会从require返回,以便可以在该脚本的本地缓存中存储它。

C代码中的另外两个问题是,数值类型真正应该被拼写为lua_Number以实现可移植性,而且验证函数所需要的参数应该使用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))

我应该补充说明,我实际上没有编译和运行上述代码,因此可能仍有几个错别字 :-)

2009-07-31 00:48:16