所以我在Visual Studio 2017中用C++编写了一个小.dll。
它所做的只是导出一个我从lua脚本调用的函数。
lua脚本在第三方应用程序中运行;我想通过该库扩展其功能。
我必须使用 package.loadlib ,因为需要修改,并且只允许加载.lua文件。 (我确认它确实找到了.dll文件,因此与包路径无关)

#include "lua.hpp"

extern "C" __declspec(dllexport) int test(lua_State* L) {
  // luaL_checknumber(L, 1); // access violation
  // lua_pushnumber(L, 123); // freeze
  return 1;
}
我使用以下代码加载此函数:
test, err = package.loadlib(dllpath, "test")

print("test = ", test, "err = ", err)
print("test() = ", test())
print("done")
打印

如预期...
但是,当我使库调用lua函数时,应用程序将永久冻结或发生访问冲突。
lua_push *函数导致这些冻结,而luaL_check *函数导致访问冲突。
我使用Windows 10(x64),应用程序为32位,我的.dll被编译为32位,并且两者具有完全相同的lua版本。
我究竟做错了什么?
编辑:
我确实联系错了。我链接到lua5.3.lib时应该是lua5.3-static.lib。我不知道。现在正在工作。

最佳答案

拥有完全相同的Lua版本是不够的。对于应用程序,尤其是游戏,修改Lua解释器非常普遍。但是,即使您具有相同的源代码,也不能在同一个程序中同时使用两份已编译的Lua C代码副本(游戏中一份,DLL中一份)。这是因为C代码使用全局变量,并且由于存在两个副本,因此它们不同步并且会导致问题。

因此,如果要调用lua_pushstring,则需要在游戏中查找该函数的地址。如果游戏是使用Lua在DLL中构建的,请找到该DLL,并使用Dependency Walker检查是否正确导出了符号。否则,请查看Dependency Walker中的EXE游戏,因为EXE也可以导出符号。找到导出Lua C API的模块(DLL或EXE)后,您可以从该模块生成一个.lib,然后将其链接到您自己的DLL中(该DLL不应该包含Lua代码本身)。

关于c++ - Lua C库访问冲突和卡住,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48614921/

10-11 22:34
查看更多