多个 C++ .lib项目到.dll项目,Lua崩溃!
今天我试图获得编辑&继续使用我的解决方案,如下所示:
Game Engine .lib <- Game .lib <- Editor .exe
<- Server .exe
<- Client .exe
效果很好。但现在我想将引擎和游戏.libs转换为.dlls,这样我就可以使用Edit &延续 Visual Studio C++ 的功能。
所以我在那里得到了一堆“__declspec(dllexport)”等,工作得很好,它运行了!
但在某些情况下它会崩溃。实际上,它总是在与释放内存相关的Lua函数中崩溃。
引擎和游戏都使用Lua,它们都有自己的静态C++接口函数。
我不确定,但我认为 .dll 有点像没有主函数的 .exe,并且每个都有自己的内存。因此,当 Game.dll 导致 Lua 分配一些内存,而 Engine.dll 导致 Lua 再次释放它时,繁荣!正确的?
关于如何解决这个问题有什么想法吗?当然Engine.dll应该负责Lua,但是Game.dll应该能够用新的静态函数扩展接口。
编辑:在我将 Lua 本身变成 .dll 后,不再发生崩溃。在尝试此操作之前,我还使用与所有其他项目相同的编译器重新编译了静态数据,并且我仔细检查了运行时库,它们都是相同的,并且我链接到正确的调试/发布库。我仍然很好奇这里发生了什么。
祝你有美好的一天,
安
东为什么我无法控制 Stackoverflow 的退货?
Today I've tried to get Edit & Continue to work in my solution, which looks like this:
Game Engine .lib <- Game .lib <- Editor .exe
<- Server .exe
<- Client .exe
Which works nicely. But now I wanted to turn the engine and game .libs into .dlls, so I can use the Edit & Continue feature of visual studio C++.
So I got a bunch of "__declspec(dllexport)"s in there, etc. works just fine, it runs!
But in certain situations it crashes. Actually, it always crashes in a Lua function that is related to freeing memory.
The engine and the game both work with Lua, they both have their own static C++ interface functions.
I am not certain, but I suppose a .dll is a bit like an .exe without a main function, and each has its own memory somehow. So when for example Game.dll causes Lua to allocate some memory, and Engine.dll causes Lua to free it again, boom! Correct?
Any ideas on how to solve this? Of course Engine.dll should be in charge of Lua, but Game.dll should be able to extend the interface with new static functions.
EDIT: There were no more crashes after I turned Lua itself into a .dll. Before I tried this I also recompiled the statics with the same compiler as all other projects, and I double checked the run time libs, and they are all the same, and I am linking to the right debug/release libs. I am still curious what's going on here.
Have a nice day,
Antoon
P.S. Why don't I have control over returns at Stackoverflow?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
你写道:
这向我表明引擎和游戏都单独静态链接到 Lua 副本的可能性。
如果这是真的,那么如果将一个副本创建的 Lua 状态传递给另一个副本,这正是您所期望发生的情况。典型的结果是弄乱内存状态并破坏分配器。根本原因是值
nil
的实现取决于Lua引擎内部某些东西的地址。链接到同一进程的引擎的第二个副本将具有不同的地址,作为其nil
的概念。这种方式最终会导致疯狂。当然,如果游戏和引擎共享 Lua 解释器的单个副本(例如都使用 LUA51.DLL),那么我就找错了树。
You wrote:
That suggests to me the possibility that the engine and game are each individually statically linked to a copy of Lua.
If that were true, then this is exactly what you would expect to happen if a Lua state created by one copy were passed to the other. The typical result is to mess up the memory state and break the allocator. The root cause is that the implementation of the value
nil
depends on the address of something inside the Lua engine. A second copy of the engine linked into the same process will have a different address serving as its notion ofnil
. That way eventually leads to madness.Of course, if the game and engine share a single copy of the Lua interpreter (say by both using LUA51.DLL) then I'm barking up the wrong tree.
也许只有我这么认为,但我发现你提供的信息有点稀疏。既然您提到您的问题与跨模块边界的内存分配有关,我会向您推荐以下文章:
链接
基本上,必须使用用于分配内存的同一分配器来释放内存,即不要混合使用 new / free - 但这也意味着您不应该分配和跨模块边界的释放内存,因为模块可能使用不同的设置进行编译,例如,调试分配器可能与发布版本中使用的分配器不同,或者由于使用的运行时版本不同(不同的版本,不同的供应商等)
大多数时候,通过提供项目中每个其他模块使用的一致接口来处理单个模块中的内存分配是最安全的。
Maybe it's just me, but I find the information you included a bit sparse. Since you mentioned that your problems are related to memory allocations across module boundaries though, I would recommend the following article to you:
Link
Basically, memory has to be freed using the same allocator that was used to allocate it, i.e. don't mix new / free - but it also means that you should not allocate and free memory across module boundaries, since modules might be compiled with different settings, for example, the debug allocator could differ from the one used in the release version, or it could be different due to different versions of the runtime being used (different release, different vendor etc.)
Most of the time it is safest to just handle memory allocations in a single module by providing a consistent interface that is used by every other module in your project.
为什么您认为需要编辑 DLL 并继续?据我使用过,它在可执行文件上也运行得很好。您遇到的某些特定错误是否导致您无法使用它?
DLL 没有自己的内存段,但它们可能使用自己的分配机制,这可能是不兼容的。请确保所有 DLL 和主程序链接到相同版本的 C 运行时库(调试或发布、多线程或非多线程以及相同的版本号)。
Why do you think you need a DLL edit and continue? It works perfectly well on executables as well, as far as I have used it. Was there some particular error you're getting that is preventing you from using it?
DLLs do not get their own memory segment, but they may use their own allocation mechanism which may be incompatible. Please ensure that all DLLs and the main program link against the same version of the C Runtime Library (Debug or release, multi-threaded or non-multi-threaded, and the same version number).
我猜想一个 DLL/EXE 分配了内存,另一个尝试释放它,然后崩溃了。
解决方案是确保所有二进制文件都使用以下任一版本进行编译:
当然,请确保所有 DLL/EXE 均使用相同的版本进行编译编译器和选项...
这是同一进程中的二进制文件(EXE 和 DLL)共享其内存分配器的唯一方法。
I guess one DLL/EXE allocated the memory, and another tries to deallocate it, and crashes.
The solution is to make sure all your binaries are compiled with either :
And of course, make sure all your DLLs/EXEs were compiled with the same compiler and options...
This is the only way for binaries (EXE and DLL) in the same process to share their memory allocators.