2009-07-30 71 views
1

我正在使用Visual Studio 2005.如何从Lua脚本中调用C++函数?

------------------------ [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)) 

回答

5

我看到几个问题。我会描述它们,并提供一个应该工作的代码片段,因为我相信你希望这个示例能够工作。

您的第一个问题是,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的便携性,并且这将是常规使用luaL_checknumber(),而不是lua_tonumber()执行所需的函数参数。就我个人而言,我会命名一个公共职能的C实现,其名称与Lua公开的名称相关,但这只是一个口味问题。

这个版本的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)) 

我要补充一点,我还没有实际编译和运行上面的,所以有可能是一个错字或两个留作练习;-)

2

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

+0

正如我在我的答案解释,这是至关重要的除非Lua核本身被编译为C++,否则luaopen_modulename()函数是extern“C”。即便如此,由于DLL的怪癖,如果在项目中使用多个编译器,最好将它留在外部“C”以避免问题。 – RBerteig 2009-07-31 06:46:38