无法使用Lua 5.4加载简单的DLL模块:“找不到指定的模块”

问题描述 投票:0回答:1

我正在尝试创建 Lua 5.4 脚本(64 位 Windows)所需的 DLL 模块。我根据我能找到的几个示例在 Visual Studio 中创建了一个简单的 DLL,但是当我尝试要求它时,我收到消息“从文件 'C:\lua estlib.dll 加载模块 'testlib' 时出错” ': 指定的模块无法找到。”从命令行以及嵌入脚本中运行

require('testlib')
时会发生这种情况。

我从 C++ 开始,因为 Visual Studio 有一个模板,但如果 C 更合适,我会很乐意切换。这对我来说是一个非常新的领域。


这是我的代码。出于初始测试目的,它只是公开一个将两个数字相加的函数,但目标是接收一个字符串并让操作系统的文本到语音读出它。我正在使用 Visual Studio 进行构建,并且依赖关系正在由 vcpkg 解决。

这是我第一次使用 c++,所以请让我知道是否有任何更重要的信息需要包含。

#include "pch.h"

#include <lua.hpp>

extern "C" {
    static int add(lua_State* L) {
        lua_Number n1 = luaL_checknumber(L, 1);
        lua_Number n2 = luaL_checknumber(L, 2);
        lua_pushnumber(L, n1 + n2);
        return 1;
    }

    static const luaL_Reg mylib[] = {
        {"add", add},
        {NULL, NULL}
    };

    __declspec(dllexport) int luaopen_testlib(lua_State* L) {
        luaL_newlib(L, mylib);
        return 1;
    }
}

BOOL APIENTRY DllMain(HMODULE hModule,
    DWORD  ul_reason_for_call,
    LPVOID lpReserved
)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

我已经查看了我能找到的所有提到此错误消息的现有帖子,但运气不佳(几乎每个示例都是为 Linux 构建的,但在我的例子中,需要为 Windows 构建)。

编辑1:这个其他问题可能算作重复,但尚未得到解答并且早于Lua 5.4。评论“C++ dll 是一种非常特殊的野兽。如果可能的话,我建议您在 DLL 上坚持使用 C,除非您真的知道自己在做什么。”表明我最好用 C 语言来做这个。我确实尝试过调整代码,但结果是一样的。尽管有人仓促下结论并删除了 C 标签,但它非常相关,所以我已经阅读了它。

编辑 2:这是我对等效 C 代码的尝试,基于 2021 年的示例。正如第一次编辑中提到的,我编译了 DLL,但在运行时收到了完全相同的错误消息(当然,新文件名除外)

require('testc')

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

static int add(lua_State* L) {
    lua_Number n1 = luaL_checknumber(L, 1);
    lua_Number n2 = luaL_checknumber(L, 2);
    lua_pushnumber(L, n1 + n2);
    return 1;
}

static luaL_Reg const mylib[] = {
    {"add", add},
    {NULL, NULL}
};

__declspec(dllexport) int luaopen_testc(lua_State* L) {
    luaL_newlib(L, mylib);
    return 1;
}
c++ c visual-c++ dll lua
1个回答
0
投票

感谢 tehtmi 的评论,我有了部分解决方案。我的代码(C 和 C++ 版本)似乎足够了,但缺少的是将 lua.dll 与 testlib.dll 或 testc.dll 一起放入运行目录中。

我不太确定我明白为什么这是必要的,但它至少清楚地表明错误指示的“指定模块”指的是lua.dll,而不是我编译的。

我能够使用 lua54.exe 在命令行上运行以下命令(其中“testlib”是我最初的 C++ 尝试,“testc”是我后来尝试的 C 版本):

> testlib = require 'testlib'
> testlib.add(2,4)
6.0
> testc = require 'testc'
> testc.add(1,2)
3.0

不幸的是,在嵌入式Lua环境(Synthesizer V Studio,一种音乐制作软件)中,结果非常不可靠。我让每个 DLL 导入一次并生成总和,但随后它们在以后的运行中反复使主机应用程序崩溃。我走开去煮咖啡,当我回来时它又开始工作,这次是多次运行。一旦我关闭并重新打开主机应用程序,就会出现更多崩溃。在这一点上,似乎每次我重新启动软件时,它是否会工作或使主机崩溃都是一个完全的折腾。

当然,这种不一致对于主机应用程序的开发人员来说可能是一个问题,如果它持续存在,我会向产品支持发送一封电子邮件,因为我知道我的代码在其他方面是有效的,但如果对 Lua 有更多经验的人看到一种模式/对此的解释,请务必让我知道。


总结剩下的问题:

  • 如果我已经在 Lua 运行时中运行它,为什么还需要单独的 lua.dll?
  • 为什么嵌入式 Lua 的行为与 lua54.exe 相比如此不一致?
  • 我可以将 lua.dll 和我的模块捆绑到同一个文件中以简化设置吗?
    • 这里的整个目标是提高主机应用程序的可访问性,因此越简单越好。
    • 当我为代码添加更多复杂性(例如调用 Windows API)时,我是否还需要分发这些 DLL?我可以只编译一个工件吗?
© www.soinside.com 2019 - 2024. All rights reserved.