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

时间:2010-08-01 22:07:48

标签: c++ dll lua swig

今天我试图让Edit&继续使用我的解决方案,如下所示:

Game Engine .lib< - Game .lib< - Editor .exe

                        <- Server .exe

                        <- Client .exe

哪个很好用。但现在我想把引擎和游戏.libs变成.dll,所以我可以使用Edit&amp;继续使用visual studio C ++的功能。

所以我在那里得到了一堆“__declspec(dllexport)”等等。工作得很好,它运行了!

但在某些情况下它会崩溃。实际上,它总是在与释放内存相关的Lua函数中崩溃。

引擎和游戏都与Lua一起使用,它们都有自己的静态C ++接口函数。

我不确定,但我想.dll有点像没有main函数的.exe,并且每个都有自己的内存。因此,当例如Game.dll导致Lua分配一些内存,而Engine.dll导致Lua再次释放它时,繁荣!正确的吗?

关于如何解决这个问题的任何想法?当然Engine.dll应该负责Lua,但Game.dll应该能够使用新的静态函数扩展接口。

编辑:在我将Lua变成.dll后,没有更多的崩溃。在我尝试这个之前,我还使用与所有其他项目相同的编译器重新编译静态,并且我仔细检查了运行时库,它们都是相同的,并且我链接到正确的调试/发布库。我仍然很好奇这里发生了什么。

度过愉快的一天,

安东

P.S。为什么我无法控制Stackoverflow的返回?

4 个答案:

答案 0 :(得分:3)

您写道:

  

引擎和游戏都与Lua一起使用,它们都有自己的静态C ++接口函数。

这告诉我,引擎和游戏各自单独静态链接到Lua的副本。

如果这是真的,那么如果由一个副本创建的Lua状态传递给另一个副本,那么这正是您所期望的。典型的结果是搞乱内存状态并破坏分配器。根本原因是值nil的实现取决于Lua引擎内部的地址。链接到同一进程的引擎的第二个副本将具有不同的地址作为其nil的概念。这种方式最终会导致疯狂。

当然,如果游戏和引擎共享一个Lua解释器的副本(比如使用LUA51.DLL),那么我就会咆哮错误的树。

答案 1 :(得分:1)

也许只是我,但我发现你所包含的信息有点稀疏。既然您提到您的问题与跨模块边界的内存分配有关,我建议您阅读以下文章:

http://blogs.msdn.com/b/oldnewthing/archive/2006/09/15/755966.aspx

基本上,必须使用用于分配内存的相同分配器释放内存,即不要混合new / free - 但这也意味着你不应该跨模块边界分配和释放内存,因为模块可能是例如,使用不同的设置编译,调试分配器可能与发布版本中使用的不同,或者由于使用的运行时版本不同(不同的版本,不同的供应商等),它可能会有所不同。

大多数情况下,通过提供项目中每个其他模块使用的一致接口,在单个模块中处理内存分配是最安全的。

答案 2 :(得分:0)

为什么您认为需要编辑DLL并继续?就我可以使用它而言,它在可执行文件上也能很好地工作。您是否遇到了一些阻止您使用它的特定错误?

DLL没有获得自己的内存段,但是它们可能使用自己的分配机制,这可能是不兼容的。请确保所有DLL和主程序链接到相同版本的C运行时库(调试或发布,多线程或非多线程以及相同的版本号)。

答案 3 :(得分:0)

我猜一个DLL / EXE分配了内存,另一个尝试解除分配,然后崩溃。

解决方案是确保使用以下任一方式编译所有二进制文件:

  • 调试多线程DLL(/ MDd)以进行调试构建
  • 发布用于发布版本的多线程DLL(/ MD)

当然,确保所有的DLL / EXE都使用相同的编译器和选项进行编译......

这是同一进程中二进制文件(EXE和DLL)共享内存分配器的唯一方法。