【问题标题】:Using custom DLL with Lua 5.1在 Lua 5.1 中使用自定义 DLL
【发布时间】:2017-03-25 15:56:02
【问题描述】:

我正在尝试使用 Lua 中的自定义 DLL。我有一个简单的 DLL,例如,像

extern "C"
{
  static int function_1(lua_State* L)
  {
    std::cout << "[DLL]this is a custom function" << std::endl;
    lua_pushnumber(L, 10);
    return 1;
  }

  __declspec(dllexport) int __cdecl luaopen_myDLL(lua_State* L)
  { 
    L = luaL_newstate();
    luaL_openlibs(L);
    std::cout << "[DLL] being initialized!" << std::endl;

    lua_register(L, "fun1", function_1);
    luaL_dofile(L, "./run.lua");
    return 1;
  }
} 

用 VS 编写并构建为 dll。

在 Lua 中运行后

package.loadlib("./myDLL.dll", "luaopen_myDLL")() 

require("myDLL")

DLL 已加载并按预期运行,并且还运行指定的 run.lua,执行 function_1 就好了。

run.lua 并没有什么特别之处,就像

f = function_1()
print("[Lua] Function_1 says", f, "\n");

我现在的问题是:

  1. 我无法从调用 DLL 的初始 Lua 脚本运行 function_1()。尝试这样做我得到了

    attempt to call global 'function_1' (a nil value)

  2. 我必须在我的 C 代码中使用 L = luaL_newstate();。出于某种原因,它不适用于传递的 lua_State*,我认为这是我无法从加载我的 DLL 的 LUA 脚本调用注册函数的原因。在运行 luaL_newstate() 之前,我的 lua_State 有一个有效地址,在 newstate 之后不会改变。

理论上,我可以从我的 C 库中运行任何 Lua 脚本来执行注册的函数,但这对我来说似乎更像是一种肮脏的解决方法。

我现在的问题是我是否遗漏了一些重要的东西?

ps:我使用的是 Lua 5.1

【问题讨论】:

  • 任何 Lua 脚本都会将您的函数视为 fun1 而不是 function_1
  • 您应该使用传递的lua_State* 而不是使用luaL_newstate 创建新的。使用传递的 Lua 状态时遇到什么错误?
  • 我当然使用了 fun1()。抱歉,我在问题中写错了。 (如前所述,当我在 C 方法使用 luaL_dofile(L, "run.lua"); 调用的 lua 脚本中使用 fun1() 时,它起作用了)当我尝试在没有 newstate 的情况下执行我的 C 代码时,我得到一个“进程完成退出代码 -1073741819 (0xC0000005)”,一旦我到达尝试使用传递状态的部分。

标签: dll lua


【解决方案1】:

下面的代码应该可以工作。由于以下原因,它可能无法工作:

  • 用于运行初始 Lua 脚本(其中包含 require("myDLL"))的二进制文件具有不同的 Lua 版本和/或不使用共享 dll。
  • 您在 C++ 代码中使用的 Lua 标头与原始 lua.exe 的 Lua 版本不同
  • 您将项目链接到不同的 Lua 版本
  • 您使用您的解决方案再次编译 Lua(如果您想使用 lua.exe,您必须使用 only 标头并且已经提供了带有 Lua 分发的 .lib 文件)

要使您的代码在 Lua 中可用,您必须使用 Lua 标头以获得正确的 Lua 版本并链接到正确的 .lib 文件并使用使用共享库(我猜是 lua.dll)的 lua.exe。

static int function_1(lua_State* L)
{
    std::cout << "[DLL]this is a custom function" << std::endl;
    lua_pushnumber(L, 10);
    return 1;
}

extern "C" int __declspec(dllexport) luaopen_quik(lua_State *L) {
    std::cout << "[DLL] being initialized!" << std::endl;
    lua_register(L, "fun1", function_1);
    luaL_dofile(L, "./run.lua");
    return 0;
}

P。 S. 请提供您的解决方案文件,以便我提供进一步帮助,因为这不是代码问题。 -- 是联动问题。

【讨论】:

  • 哦,非常感谢。我确实在创建我的 DLL 的 VS 解决方案中链接到不同的 LUA。非常感谢。
猜你喜欢
  • 1970-01-01
  • 2021-12-31
  • 2021-09-20
  • 2019-03-10
  • 1970-01-01
  • 2011-02-16
  • 2015-12-24
  • 1970-01-01
  • 2012-11-03
相关资源
最近更新 更多