STL and DLLs not compatible?

Started by
10 comments, last by Promit 18 years, 4 months ago
After giving up on DLLs in the past, i have decided to give it another try. My framework is currently built as a static library, but i wish to distribute it. The problem with static libraries is that MSVC builds a 16mb .lib file. The resulting executable of a simple application from the use of the library is 100kb. The other problem is that i will have to distribute all the static library dependancies instead of just 1 dll file. I came across an article on msdn which says that STL cannot be used when building DLLs with the exception of std::vector. I have no intention to rewrite my code because i make use of list,map. But i find it strange to know that all applications which use DLLs dont make use of STL? Or is there a workaround?
Advertisement
i'd like to add another very related question, if i may. when you use the stl containers does it matter if your dllexported set of functions is marked with extern "C" ? i mean if you don't extern"C" the compatibility to other compilers of the compiled dll will be lost.. but maybe we gain benefits in terms of the variety of containers used as parameters?

regards,
simon.
DLLs were not designed with C++ constructs in mind. The fact that you can export classes and the like is really no more than a glorious hack. I recommend restricting interfaces exposed in DLLs to C constructs. If you can't do that, try to limit your exposed classes to abstract interfaces with no member variables and provide factory functions for these classes. Implementation details should be completely hidden.
What exactly do you mean by C constructs?

Quote:
If you can't do that, try to limit your exposed classes to abstract interfaces with no member variables and provide factory functions for these classes.


I havnt even gotten past the stage of successfully compiling my dll let alone using it. By factory functions do you mean something like a Singleton where you have to do Class::getClass().myFunction();

In such a case, where is the pointer new-ed?
Is it in the dll code, or does the client using the dll new it?

Also even in cases where i am not exposing the STL member object(making it private), i still get hundreds of warnings. So i followed the method described in this article. Basically im forcing the the compiler to export the instantiation of the vector. Is this method good? Will it create problems in the future for me?

class DLLImportExportMacro AClass

{
public:
std::vector<int> GetVariable() { return y; }
protected:

template class DLLImportExportMacro std::allocator<int>
template class DLLImportExportMacro std::vector<int,
std::allocator<int> >;
std::vector<int> y;
};

My preferred way to expose C++ classes from a DLL is like so:
//in a global header:struct IStuff{    virtual void Foo() = 0;};typedef IStuff* (*StuffCreatorFunc)();typedef void (*StuffDestroyerFunc)( IStuff* );//in the DLLclass ConcreteStuff : public IStuff{public:    virtual void Foo();};extern "C" DLLEXPORT IStuff* StuffCreator(){    return new ConcreteStuff;}extern "C" DLLEXPORT void StuffDestroyer( IStuff* stuff ){    delete stuff;}

Now you reference the StuffCreator and StuffDestroyer functions in your main executable and call them to manage your pointers.

Also, I'd suggest you read Washu's journal entries on DLLs.
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
Quote:Original post by GamerSg
What exactly do you mean by C constructs?

Things that would compile under a C compiler.

Quote:
I havnt even gotten past the stage of successfully compiling my dll let alone using it. By factory functions do you mean something like a Singleton where you have to do Class::getClass().myFunction();

Functions that return pointers to newly constructed classes, like Promit has in his post.

Quote:
In such a case, where is the pointer new-ed?
Is it in the dll code, or does the client using the dll new it?

Inside the DLL code.

Quote:
Also even in cases where i am not exposing the STL member object(making it private), i still get hundreds of warnings.

If it's in the header it's still exposed, even if you make it private. Make an abstract base class with no member variables and derive the class you create in your DLL from that and then have the factory function return a newly created instance of the derived class.

Quote:
So i followed the method described in this article. Basically im forcing the the compiler to export the instantiation of the vector. Is this method good?

Not really.

Quote:
Will it create problems in the future for me?

Probably if you try to mix multiple DLLs that all try to export std::vector. Or try to use the header file on a different compiler, or on the same compiler with different compile flags, etc.
Quote:Original post by SiCrane
DLLs were not designed with C++ constructs in mind. The fact that you can export classes and the like is really no more than a glorious hack. I recommend restricting interfaces exposed in DLLs to C constructs. If you can't do that, try to limit your exposed classes to abstract interfaces with no member variables and provide factory functions for these classes. Implementation details should be completely hidden.

....


Make an abstract base class with no member variables and derive the class you create in your DLL from that and then have the factory function return a newly created instance of the derived class.



*nods* It's all about creating decent abstract interface classes.
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.
But wouldnt doing this for every class be overkill and alot of work?

What about simple classes like Point3, Quat, KeyEvent, etc...?
Simple classes like that don't belong as DLL exported classes. Those kinds of classes have member functions that usually belong as inline functions, which shouldn't be exported.
The only real way to guarantee that your application will work with a DLL with C++-exported classes and functions is if the DLL was compiled with the same version of the same compiler as the application you're trying to use the DLL with. If that requirement can be satisfied, you should be able to safely export things. Unfortunately this means creating a library for wide distribution could prove to be difficult, but if you've got a controlled library and application setup then you should be fine.

This topic is closed to new replies.

Advertisement