我怎样从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
我发现了几个问题。我将描述这些问题,并提供一个代码片段,应该能够按照你打算的方式使这个示例运作。
你的第一个问题是,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))
我应该补充说明,我实际上没有编译和运行上述代码,因此可能仍有几个错别字 :-)
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
- 如何编写 Lua 模式将字符串(嵌套数组)转换为真正的数组?
如果您正在编译为 C++ 并且想要匹配一个 'C' 接口,您应该将外部可见函数声明为
extern "C"
,以避免名称混淆。