tags:

views:

46

answers:

4

Hello,

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?

A: 

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).

Dark Falcon
Xilliah
Thank you, I missed the static libraries part. I don;t normally work with them much myself.
Dark Falcon
+1  A: 

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:

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

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.

Jim Brissom
Interesting, because I am sure Lua was the one who allocated and freed the memory. And the run time libraries were all set to the same, and all projects including Lua were compiled with the same compiler. Perhaps one or two options were different. I always find it hard to compare compiler options in VS.
Xilliah
A: 

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 :

  • Debug Multithread DLL (/MDd) for debug builds
  • Release Multithread DLL (/MD) for release builds

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.

paercebal
+2  A: 

You wrote:

The engine and the game both work with Lua, they both have their own static C++ interface functions.

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 of nil. 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.

RBerteig
This is the answer, thank you sir! Yes I did statically link it to Engine.dll and Game.dll, because originally Engine.lib would link it, and Game.lib would automatically inherit the symbols of course.And yes, turning Lua into a dll fixed it.Very interesting bug =).
Xilliah