我正在使用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))
RBerteig.. 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))
我应该补充一点,我实际上并没有编译并运行上面的内容,所以可能会有一两个错误或者两个作为练习;-)
我看到几个问题.我将描述它们,并提供一个代码片段,应该可以工作,因为我相信你希望这个样本工作.
你的第一个问题是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))
我应该补充一点,我实际上并没有编译并运行上面的内容,所以可能会有一两个错误或者两个作为练习;-)