我看到了几个问题。我将对它们进行描述,并提供一个代码片段,我相信它应该可以按照您希望此示例正常工作的方式工作。
您的第一个问题是 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() 的函数。
需要“luapassing”
打印(“你好”)
打印(luapassing.dothis(120))
我应该补充一点,我实际上并没有编译和运行上面的代码,所以可能会有一两个错字作为练习;-)