Lua加载dll扩展时崩溃
2016-9-8 19:16:27
收藏:0
阅读:112
评论:1
我正在尝试在Windows上创建Lua dll扩展。我正在使用Lua 5.3。我的编译器是来自MinGW的gcc 4.9.3。
我的dll扩展的C代码类似于这样:
#include <stdio.h>
#include <lua.h>
static int dub(lua_State *L) {
const double a = lua_tonumber(L, 1);
lua_pushnumber(L, a*2);
return 1;
}
__declspec(dllexport) int __cdecl luaopen_mylib(lua_State *L){
printf("One\n");
lua_pushcfunction(L, dub);
printf("Two\n");
lua_setglobal(L, "dub");
printf("Three\n");
return 1;
}
我这样编译我的dll:
gcc mylib.c -shared -o mylib.dll -llua
想法是我可以从Lua中加载它并像这样使用它:
require "mylib"
print (dub(5)) --应该打印10
但是,当我实际尝试运行Lua代码时,在require "mylib"行上崩溃了。 DLL能够打印“One”和“Two”,但在崩溃之前无法打印“Three”。这告诉我问题可能与'lua_setglobal'调用有关。
出了什么问题?我如何进一步调试或修复它?
作为一个额外的问题:luaopen_mylib的返回值应该是什么?
谢谢!
点赞
评论区的留言会收到邮件通知哦~
推荐文章
- Lua 虚拟机加密load(string.dump(function)) 后执行失败问题如何解决
- 我想创建一个 Nginx 规则,禁止访问
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在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 代码?

我编译了你的代码并且它很好地工作了。所以你的问题不是来自你的代码。我的猜测是你正在使用不同版本的Lua,或者链接出现了问题。
三个可能出现版本不匹配的地方如下:
#include <lua.h>行中-llualua可执行文件时这三个必须是相同的Lua版本。如果其中一个不匹配,那就可能会导致你遇到的问题。我猜测你的Lua可执行文件版本与其他版本不匹配。
另一个需要尝试的方法是,你的dll库应该链接到Lua的dll库。你的系统上应该有一个名为
lua53.dll的文件。将它复制到你的构建目录中。当你用gcc编译时,试着这样做:gcc mylib.c -shared -o mylib.dll lua53.dll这意味着你的dll扩展调用的正是Lua可执行文件使用的完全相同的Lua代码。现在你的方式,使用
-llua行,看起来你正在静态链接Lua。这几乎永远不是dll库中想要的,因为Lua可执行文件将调用lua53.dll中的代码,而你的dll库将调用静态库中的不同代码。我不认为仅仅这样会导致你的崩溃,但这不是很好的做法。如果Lua使用的是全局状态(它没有这样做),这个链接问题肯定会导致崩溃。此外,如果你编译成lua53.dll,你会发现mylib.dll更小。_总之_,我认为你的Lua版本在某个地方不匹配,导致了你的崩溃。你还应该链接到Lua的dll库,而不是静态库,以符合良好的规范。
在你的代码中,它实际上应该是
0而不是1。返回值是你希望require()调用返回的栈上剩余的元素数。你的库只是将自己塞入全局状态中,不返回任何Lua值。一个替代的方法是返回一个包含库函数的表。这样你就不会污染全局状态了。由于你的库只有一个函数,你可以像这样直接返回它:__declspec(dllexport) int __cdecl luaopen_mylib(lua_State *L){ lua_pushcfunction(L, dub); return 1; }然后你可以像这样从Lua中使用它:
local dub = require("mylib") print (dub(5)) --应该打印10我更喜欢这种方法,因为调用者可以决定导入的名称,它不会污染全局空间。