std::string in DLLs

Started by
3 comments, last by dalleboy 18 years, 11 months ago
Hello All, I'm sure someone else has run into this problem, so I am curious how you solved it. When using STL containers, I run into memory allocation problems when passing containers (particularly strings) back and forth across the DLL/EXE boundary. It seems that if the string is longer than 16 characters, the string class is reallocating some memory during construction, and you essentially have two separate chunks of memory on two different heaps. Then it runs into problems when it tries to clean these up, because of the separate heaps. I'm sure I'm not the first person who has tried to use std::string in a DLL, so I'm wonder how other people handled this. Thanks
SilverFan and Programmer of GamesDefender of Freedom
Advertisement
Basically, you don't want to be passing strings around across DLLs that you will be changing at all. If you will have to manipulate some text, pass it across the boundaries as a const char *, construct a string from it, manipulate the string, and pass back another const char *, based on the new string. This is, at least, the info I've gathered from reading these forums, googling, etc. The general concensus is that you don't want to be passing standard C++ containers (it's not STL anymore) across modules.
Free speech for the living, dead men tell no tales,Your laughing finger will never point again...Omerta!Sing for me now!
Another reason (amongst many), that made me write my own string class (which is completely DLL safe). Not being able to pass non-const maps, vectors or lists to or from a DLL is already limiting enough, but it is completely unacceptable with strings. The char* hack is ridiculous.

But even when using std::string, there is probably a way around by supplying your own allocator, which would always operate on a single heap, through a separate DLL-host allocation interface function.

Overloading the global new and delete operators, ie. completely replacing the memory allocation system in host and DLL by your own single heap one, is another approach to look into. Although you should be careful when doing that, it can break other things (especially when mixing pointers from precompiled third party libraries).
I think I've found the solution... I'm suprised this information isn't more abundant, but here's it is. This seems to allow any STL container to be used with DLLs.

http://support.microsoft.com/default.aspx?scid=kb;EN-US;q168958
SilverFan and Programmer of GamesDefender of Freedom
If the DLL and the EXE are using the same C++ runtime/standard library there shouldn't be a problem as the DLLs and the EXE uses the same heap. If you are the developer of both the DLL and the EXE you can control this, but if the DLL is written by someone else (i.e. if you have bought it from another company) you can get into these problems.

Lets say you have written an application named SuperGame.exe, this uses the Microsoft implementation of the C++ standard library (msvcp71.dll for VC 7.1).

After a while you decide that in your game you'll need an Xml parser, and you find an open source version on the internet and download it. The problem with this Xml parser is that it uses StlPort, an alternative implementation of the C++ standard library (i.e. stlport46.dll).

msvcp71.dll <- SuperGame.exe
stlport46.dll <- XmlParser.dll

SuperGame.exe runs perfectly fine unless when it use std::strings returned from functions in XmlParser.dll. Why is that, and why does it work? SuperGame.cpp includes the "XmlParser.h" header, which in turn includes the <string> header, the compiler uses the configured include paths to find the <string> header. What it finds is the Microsoft implementation, even though the XmlParser.dll is compiled using the StlPort implementation. By now the compilation is in really bad shape, but the compiler doesn't realize it. The compilation and linking succeeds and SuperGame.exe is created.

But what happens when the application is run is another thing. When SuperGame.exe calls a function in XmlParser.dll that returns a std::string a similar thing as a cast is made from a stlport::std::string to a msvc::std::string. After that "cast" is done anything can happen, as usual with casts.
Arguing on the internet is like running in the Special Olympics: Even if you win, you're still retarded.[How To Ask Questions|STL Programmer's Guide|Bjarne FAQ|C++ FAQ Lite|C++ Reference|MSDN]

This topic is closed to new replies.

Advertisement