多个C++ .lib项目到.dll项目,Lua崩溃!

n3schb8v  于 2023-04-23  发布在  其他
关注(0)|答案(4)|浏览(206)

今天,我尝试在我的解决方案中使用Edit & Continue,它看起来像这样:
Game Engine .lib〈- Game .lib〈- Editor .exe

<- Server .exe

                        <- Client .exe

这很好用。但是现在我想把引擎和game .libs变成. dll,这样我就可以使用visualstudioc 的编辑和继续功能了。
所以我在里面放了一堆“__declspec(dllexport)“,等等。工作得很好,它运行得很好!
但在某些情况下它会崩溃。实际上,它总是在与释放内存相关的Lua函数中崩溃。
引擎和游戏都使用Lua,它们都有自己的静态C
接口函数。
我不确定,但我认为.dll有点像没有main函数的.exe,每个都有自己的内存。因此,例如Game.dll导致Lua分配一些内存,而Engine.dll导致Lua再次释放它,boom!正确吗?
当然Engine.dll应该负责Lua,但是Game.dll应该能够用新的静态函数扩展接口。
编辑:在我把Lua本身转换成. dll之后,没有再发生崩溃。在我尝试这个之前,我也用和所有其他项目相同的编译器重新编译了静态数据,我仔细检查了运行时库,它们都是一样的,我链接到了正确的调试/发布库。我仍然很好奇这里发生了什么。
祝你今天愉快
安东
P.S.为什么我不能控制Stackoverflow的回报?

kyxcudwk

kyxcudwk1#

你写道:
引擎和游戏都使用Lua,它们都有自己的静态C++接口函数。
这向我暗示了引擎和游戏各自单独静态链接到Lua副本的可能性。
如果真是这样如果一个副本创建的Lua状态被传递给另一个副本,那么这正是你所期望发生的事情。典型的结果是混乱内存状态并破坏分配器。根本原因是值nil的实现依赖于Lua引擎内部的某个东西的地址。链接到同一个进程的引擎的第二个副本将有一个不同的地址作为它的nil概念,这种方式最终会导致疯狂。
当然,如果游戏和引擎共享Lua解释器的一个副本(比如都使用LUA51.DLL),那么我就找错了对象。

yptwkmov

yptwkmov2#

也许只是我,但我发现你包含的信息有点稀疏。因为你提到你的问题与跨模块边界的内存分配有关,我会向你推荐以下文章:
Link
基本上,内存必须使用用于分配它的相同分配器来释放,即不要混合new / free -但这也意味着您不应该跨模块边界分配和释放内存,因为模块可能使用不同的设置进行编译,例如,调试分配器可能与发布版本中使用的不同。或者由于所使用的运行时的不同版本(不同的发布、不同的供应商等)而不同。
大多数情况下,最安全的方法是在单个模块中处理内存分配,方法是提供一个一致的接口,供项目中的所有其他模块使用。

qvk1mo1f

qvk1mo1f3#

为什么你认为你需要一个DLL编辑并继续?它在可执行文件上也工作得很好,就我所使用的来说。是不是有一些特殊的错误阻止了你使用它?
DLL不获取自己的内存段,但它们可能使用自己的分配机制,这可能是不兼容的。请确保所有DLL和主程序链接到同一版本的C运行时库(调试或发布,多线程或非多线程,以及相同的版本号)。

shyt4zoc

shyt4zoc4#

我猜是一个DLL/EXE分配了内存,而另一个DLL/EXE试图释放它,然后崩溃了。
解决方案是确保所有的二进制文件都是使用以下两种方法之一编译的:

  • 为调试版本调试多线程DLL(/MDd)
  • 发布版本的多线程DLL(/MD)

当然,确保所有的DLL/EXE都是用相同的编译器和选项编译的。
这是同一进程中的二进制文件(EXE和DLL)共享其内存分配器的唯一方法。

相关问题