You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Win x64下Lua调用DLL返回函数而非数值且Lua53崩溃求助

Lua调用DLL函数返回函数而非预期数值,Lua5.3运行崩溃问题

环境与现象

  • 运行环境:Win x64 系统,使用 lua53.exe 或 lua54.exe
  • 操作逻辑:通过 package.loadlib 加载 jsyslog.dll 中的 test 函数,预期调用 test() 返回数值3
  • 实际结果:
    • 输出两次 Test result function: 00000000704186d0
    • lua53.exe 执行后直接崩溃
    • lua54.exe 无崩溃,但返回的是函数对象而非预期的数值3

问题根源

  1. package.loadlib 的调用要求:该函数加载DLL导出函数后,返回的可调用对象要求导出函数必须严格遵循Lua C API规范——即函数签名为 int lua_CFunction(lua_State *L),通过操作Lua栈传递参数和返回值,返回值为栈上结果的数量。
  2. DLL函数不符合规范:若 jsyslog.dll 中的 test 是普通C函数(比如直接返回int的 int test()),而非适配Lua的C函数,调用时会破坏Lua栈结构,导致Lua5.3崩溃;Lua5.4虽有栈保护,但无法将普通函数的返回值转为Lua数值,因此返回的仍然是加载后的函数对象。

解决方案

方案1:修改DLL代码,遵循Lua C API规范

重新编译 jsyslog.dll,让 test 函数适配Lua的C函数要求:

#include <lua.h>
#include <lauxlib.h>

// 符合Lua C API的test函数
static int test(lua_State *L) {
    lua_pushinteger(L, 3); // 将数值3压入Lua栈
    return 1; // 返回栈上结果的数量(此处为1个)
}

// 定义库函数表
static const luaL_Reg jsyslog_lib[] = {
    {"test", test},
    {NULL, NULL} // 表结束标记
};

// 库的入口函数,供Lua加载
int luaopen_jsyslog(lua_State *L) {
    luaL_newlib(L, jsyslog_lib);
    return 1;
}

编译后,可通过以下Lua代码调用:

-- 方式1:用require加载库
local jsyslog = require("jsyslog")
local result = jsyslog.test()
print("Test result", result)

-- 方式2:用package.loadlib加载入口函数
local load_lib, err = package.loadlib("jsyslog.dll", "luaopen_jsyslog")
if not load_lib then error(err) end
local jsyslog = load_lib()
local result = jsyslog.test()
print("Test result", result)

方案2:使用FFI调用普通C函数(无需修改DLL)

如果无法修改DLL,可借助Lua的FFI库(LuaJIT内置,Lua5.4可使用第三方luaffi库)直接调用普通C函数:

local ffi = require("ffi")
-- 声明函数原型
ffi.cdef[[
    int test();
]]
-- 加载DLL并调用函数
local jsyslog = ffi.load("jsyslog.dll")
local result = jsyslog.test()
print("Test result", result)

内容的提问来源于stack exchange,提问作者josh assing

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 15:52:17