Sign in to follow this  
3DModelerMan

Converting STL heavy static library to shared

Recommended Posts

3DModelerMan    1173

I've got a static library that's pretty STL heavy that I need to convert to a shared library. I've heard a lot of things about STL being bad in shared libraries, but none of the topics I could find really mentioned a couple specifics I was wondering about. 

 

If the STL usage is kept to the library's implementation and is only used internally for implementation, then would it still introduce problems? Also, some of the methods take a reference to a vector and fill it with objects, am I going to be forced to roll my own data structures for these cases? And same with areas where strings need to be returned and/or passed (some I might be able to get away with converting to C-style strings, but an actual string class would be much better).

Share this post


Link to post
Share on other sites
frob    44904
Reiterating, the problem is not about if the library is static or dynamic or any such things. The problem ensuring safe conditions when crossing boundaries.

If you say "here is a pointer to a c-style string" or "here is a 32-bit value" there are no problems. Data is transferred and read, but as long as each side is responsible for their own internal work everything works just fine.

When you start to pass around larger objects there is potential for problems. One side might have some build-specific data members (like debug variables) so that the two structures are not identical, one may have 16 data members but the other has 18. As long as the data members and the layout match, most of those concerns go away. If you end up modifying a shared data structure you need to rebuild everything on both sides to keep them in sync, but in the grand scheme of things this is not a problem.

The other big issue is when you pass around things that rely on other systems, like memory management. If one side is using a certain memory manager, and the other side is using a different memory manager, and then both sides are attempting to manipulate the memory, the two will behave in incompatible ways and really bad things are going to happen. Most of the container classes are a great example of this. Since container classes tend to have their functions get inlined and container classes can modify large blocks of memory, programmers must be careful that both sides are using compatible functions. One side uses a debug allocator that puts a nice little border around it and tracks the memory, then the other side resizes the memory with a non-debug allocator and releases the debug-tracked block with a non-debug function and suddenly all kinds of nightmare scenarios can play out. Memory management is probably the most common item, but it applies to any set of functions. If one side behaves in a way that is incompatible with the other side, errors will result.

As long as both sides (the main executable and the external libraries) are compiled with the same settings and the same combination of libraries everything is fine. The data structures will be the same size, with the same alignment, and they'll be using the same libraries for external functionality.

Share this post


Link to post
Share on other sites
SeanMiddleditch    17565

As long as both sides (the main executable and the external libraries) are compiled with the same settings and the same combination of libraries everything is fine. The data structures will be the same size, with the same alignment, and they'll be using the same libraries for external functionality.


The simple common case here is that if you're talking about a shared library you ship with your game's executable, you most likely don't need to worry about it.

Share this post


Link to post
Share on other sites
Jason Z    6434


If the STL usage is kept to the library's implementation and is only used internally for implementation, then would it still introduce problems?
If you are 100% certain that the STL usage of the shared library is only internal, then you are ok in theory.  In reality, that is usually pretty hard to isolate and it takes some serious dedication to make sure non of your interface exposes STL types in any way.  In addition, the types of bugs that can be produced with this include memory corruption which can be notoriously difficult to track down.

 

My advice is that unless you are absolutely certain that you need a shared library, stick with a static library.  If you must use a shared library, make sure that your projects are always compiled in tandem with the same settings.  If you are using Visual Studio, this is pretty easy to do with the configuration management system, but easy to mess up if you manually introduce compilation flags in one project but not in the others.

Share this post


Link to post
Share on other sites
King Mir    2490

As long as your shared library doesn't expose STL containers as part of its interface, there's no problem. So you do want to roll your own types for passing data in and out.

 

Then you have to make sure your library has a stable ABI itself while still being amendable to bug fixes and expansion. This is mainly done by using the PImpl pattern. The details of what you can change while maintaining ABI compatibility is different between MSVS and Gcc.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this