DLL with STL Woes

This topic is 4886 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

Having a little extra time this holiday, i decided to compile my engine as a DLL. This is my first experience with DLLs and it has almost made me give up the idea. Previously the code compiled as a static library with no warnings/errors. From the errors, it appears that i need STL to have a dll-interface before my classes can use STL objects. After some thorough searching, i also came across an article on MSDN stating that while there are workarounds to get STL working, i won't be able to use some containers. Most notably std::list and std::deque. To me it is not worth the effort to spend a whole week and change my code so that it may compile to a dll. And not being able to use STL containers? Im sure there is a workaround, but i have not been able to find a solution yet.

Share on other sites
Yeap, that's about it - you simply cannot use some containers with STL in .dlls. I understand your feelings - it took me a while to figure out the whole using STL in .dlls when I converted my engine into a .dll. There is no work around except make your own container classes instead of using theirs. So for you, it would not be worth the effort to make it into a .dll. I hope this helps a bit.

- Drew

Share on other sites
You could try another STL implementation, like STLPort (google for it)

Share on other sites
I know of STLPort, but can it be used in DLLs?
Would'nt STLPort have the same restrictions as the MSVC implementation?

Share on other sites
Sure you can:

#ifndef SPRY_INTERNAL_ALLOCATOR_HPP#define SPRY_INTERNAL_ALLOCATOR_HPP#include <limits>#include <windows.h>namespace Spry{namespace Internal{	template<typename T>	class Allocator	{	public: 		typedef T					value_type;		typedef value_type*			pointer;		typedef const value_type*	const_pointer;		typedef value_type&			reference;		typedef const value_type&	const_reference;		typedef std::size_t			size_type;		typedef std::ptrdiff_t		difference_type;	public : 		template<typename U>		struct rebind		{			typedef Allocator<U> other;		};	public : 		explicit Allocator()		{		}		~Allocator()		{		}		explicit Allocator(Allocator const&)		{		}		template<typename U>		explicit Allocator(Allocator<U> const&)		{		}		pointer address(reference r)		{			return &r;		}		const_pointer address(const_reference r)		{ 			return &r;		}		pointer allocate(size_type cnt, typename std::allocator<void>::const_pointer = 0)		{ 			return reinterpret_cast<pointer>(HeapAlloc(GetProcessHeap(), 0, (cnt * sizeof (T)))); 		}				void deallocate(pointer p, size_type)		{ 			HeapFree(GetProcessHeap(), 0, p); 		}		size_type max_size() const		{ 			return std::numeric_limits<size_type>::max() / sizeof(T);		}		void construct(pointer p, const T& t)		{ 			new(p) T(t); 		}		void destroy(pointer p)		{			p->~T();			p = 0;		//unnecessary in this scope, but silences warnings		}		bool operator==(Allocator const&)		{			return true;		}		bool operator!=(Allocator const& a)		{			return !operator==(a);		}	};}}#endif

Use this class as the allocator for whatever STL container you are using:
std::list<Class*, Spry::Internal::Allocator<Class*> > list;

I don't recommend it, but that doesn't stop most people. :) I think too many people worry about making 'extensible' engines through DLLs rather than just finishing what they have.

Share on other sites
Quote:
 Original post by antareusI think too many people worry about making 'extensible' engines through DLLs rather than just finishing what they have.

Well I think that is kinda of right - but also you have to consider the fact that using an engine via a .dll is more fun than finishing it [smile]. Seriously though , by getting it into a .dll you can use it (the unfinished engine) a lot easier in test projects compared to copy-pasting code - that is if you have a large library.

As for your tip - what does that exactly do? Use STL in a .dll or let you use STLPort?

- Drew

Share on other sites
It uses the heap that is allocated to the process, instead of the private ones used by the module's C runtime library.

Share on other sites
I'm rather confused. Where exactly did you read that you cannot use some of STL in a DLL? What compiler is this to do with?

We use STL extensively at work with .NET and most of our code is in DLLs and we've never had any problem.
Maybe you're trying to use it between the DLL and the EXE? Perhaps each STL container should be entirely contained within the DLL or the EXE. i.e. use accessor functions instead of passing the list between DLL & EXE.

Share on other sites
Quote:
 Original post by iMalcI'm rather confused. Where exactly did you read that you cannot use some of STL in a DLL? What compiler is this to do with?We use STL extensively at work with .NET and most of our code is in DLLs and we've never had any problem.Maybe you're trying to use it between the DLL and the EXE? Perhaps each STL container should be entirely contained within the DLL or the EXE. i.e. use accessor functions instead of passing the list between DLL & EXE.

Quote:
 Note that you may not export a generalized template. The template must be instantiated; that is, all of the template parameters must be supplied and must be completely defined types at the point of instantiation. For instance "stack;" instantiates the STL stack class. The instantiation forces all members of class stack to be generated.Also note that some STL containers (map, set, queue, list, deque) cannot be exported. Please refer to the More Information section to follow for a detailed explanation.

MSDN. You have to use IE to view the page - it will not work correctly in FireFox.

- Drew

Share on other sites
Quote:
 Note that you may not export a generalized template. The template must be instantiated; that is, all of the template parameters must be supplied and must be completely defined types at the point of instantiation. For instance "stack;" instantiates the STL stack class. The instantiation forces all members of class stack to be generated.Also note that some STL containers (map, set, queue, list, deque) cannot be exported. Please refer to the More Information section to follow for a detailed explanation.

This is true, but it doesn't mean you can't use the STL containers. The same code will be generated in both the DLL and EXE for the container, so reading from a list in an EXE that was created in a DLL isn't a problem. Problems occur when you modify the list (adding/removing nodes, changing the value of a node is OK) as this could result in allocating or releasing memory on different heaps (the EXE's and the DLL's)....things start to go *splat*.

antareus's solution prevents this from happening. The allocator object explicitly allocates & releases memory on the EXE's heap, so even if the allocator is called (by the container) from within the DLL the container will always be using the EXE's heap for allocating & releasing memory.

• 10
• 18
• 14
• 18
• 15