Skip to main content
GameDev.net gamedev.net
🔒 Locked

Dll issues

Started by Valor Knight May 11, 2006 at 7:26 PM 8 replies 1.3k views
Original Post
Valor Knight
Valor Knight
I have 2 issues with my dll's in my program 1: I instanced out a class in my program from a lib. I can use the instanced class all I want in my normal program, but once I pass it by pointer to a function in a dll, when it tries to new() anything (I am assuming, because I can change varibles, just cant create a resource - calling new Texture()) It fails, and gives me the heap source as in that is what is failing, in there. -Can I do this, I mean is it legal, or is it my programming in functions being called not dll worthy? -As I said it works perfect in my main program, I can create texture resources(from a lib) and use it, I can even pass a refrence to that resource to the dll, and the dll will work with it fine, I just cannot create resources in the dll, which i need to do.. -Need more info? 2: I have currently 2 dlls and several libs. Is it possible to create one project dll that can contain all the other dlls so I only need to update a few? Thanks
There is no life without honor
etothex
etothex
You cannot share heap calls across dll boundaries (i.e., call new in the dll and delete in the main program, or vice versa)

Someone more familiar with creating windows dlls will have to follow up with more info.

[Edited by - etothex on May 12, 2006 12:38:09 AM]
Extrarius
Extrarius
The easist fix is to set your program and all dlls to use the DLL version of the runtime. That way, only one instance of runtime will exist and the program and dlls will share it.
When you use the default static verion of the runtime, the dll and exe have their own copy of the runtime, so anything allocated in a DLL will only be known by that DLL (for re/de allocation purposes) and likewise for the main program.
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk
hplus0603
hplus0603
More importantly, all DLLs who participate, and your EXE, need to share the same version of the CRT library. If one DLL is compiled with VS 6.0; one is compiled with MinGW, and one is compiled with VS 2005, they will be using different versions of the C runtime, and unbalanced new/delete won't work.

The best way to deal with this is to use factory functions, and a Dispose() method on your classes, and make the constructor/destructor protected. Or go for COM, with reference counting.
enum Bool { True, False, FileNotFound };
etothex
etothex
Quote:
Original post by Anonymous Poster
> You cannot share heap calls across dll boundaries

Yes, you can. You need to tell the linker to use the DLL-able version of the CRT. Check the linker commands /MD and /MDd. Compile all the DLLs and the EXEs using /MD (/MDd is the debug version) and the CRT (C Runtime Library) will be shared between the application and all the DLLs.


Really? Is this with newer versions of VC++ or is it something I've just been stupid about for a long time?
Valor Knight
Valor Knight
Quote:
Original post by Extrarius
The easist fix is to set your program and all dlls to use the DLL version of the runtime. That way, only one instance of runtime will exist and the program and dlls will share it.
When you use the default static verion of the runtime, the dll and exe have their own copy of the runtime, so anything allocated in a DLL will only be known by that DLL (for re/de allocation purposes) and likewise for the main program.


So, if I instance a texture resource manager in one dll, I can't use it in the main program and other dll's unless I do a /MD /MDd?

The /MD makes it multi-threaded (according to VS2003) - I assume there is a penalty for this option

So if I have a class hat is being instanced in the program, or another dll, and the main program instances it, and calls a function in it (requestTexture()) and that function new()s something, then it is being used by diffrent runtimes if it is being used in a different dll or the main progam? The only way to stop this woud be to make it(the dll) and everything else used by the program multi-threaded?

[Edited by - Valor Knight on May 12, 2006 1:23:54 AM]
There is no life without honor
Extrarius
Extrarius
The "multiple runtimes" problem exists when you try to do memory management in different places (ie new in exe, then delete in dll). As long as each module only deletes things it newed, most things will work fine. However, if you're using dlls in the first place, chances are that you're dealing with multithreading and should the multithreaded runtime.

There is some very slight penalty associated with using the multithreaded runtime, but it's so small that it should be irrelevant except in the most extreme cases. It might matter for john carmack, but probably doesn't for you. Basically, the difference is that normally, a function call is done directly, while with a dll (which is what the multithreaded runtime is), the call must jump to two places (basically it says "jump to wherever that function is" which jumps to a lookup table, then it says "jump to the real address" because windows patched up the lookup table with the correct addresses).
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk
Evil Steve
Evil Steve
Quote:
Original post by etothex
Really? Is this with newer versions of VC++ or is it something I've just been stupid about for a long time?
It's been around since VC6 I believe, possibly before.

Quote:
Original post by Valor Knight
The /MD makes it multi-threaded (according to VS2003) - I assume there is a penalty for this option
Compiling as multithreaded, or linking to the multithreaded CRT causes all heap accesses to get chucked through a mutex. So there is a slight penalty, but it's nessecary if you're in a multithreaded environment. The other alternative of course is to have one heap per thread. But then you have to make sure that one thread only accesses one heap, although I suspect there's other parts of the CRT that get mutex locked in a multithreaded environment.
paulecoyote
paulecoyote
I'll just add my 2c / 2p [smile]

For sanities sake it is easier to keep things exported to and from dlls being primitive types such as const char* and long, and your own interface classes (class that has no member variables, just abstract functions (virtual void foo() =0;). Anything more complex and you start coming across problems described throughout the rest of the thread.

Another guideline is that memory that is allocated on one side of a dll boundary should be deallocated on that same side.

Though those guidelines can be flouted, keeping to them might mean you don't have to worry so much about what versions of the libraries were used on either side. Mixing debug and release dlls is still a bit of a no-no though - and you sometimes you can get wierd errors even following that if you mix different threading standards.

To get around wanting to create concrete instances of your interfaces without exposing the concrete class for export, you should follow a factory pattern. This means you can create concrete instances of classes that implement your exposed interfaces, without exposing your concrete implementation header files that may use the stl or whatever.
Anything posted is personal opinion which does not in anyway reflect or represent my employer. Any code and opinion is expressed “as is” and used at your own risk – it does not constitute a legal relationship of any kind.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.