DLL with STL Woes
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.
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
- Drew
I know of STLPort, but can it be used in DLLs?
Would'nt STLPort have the same restrictions as the MSVC implementation?
Would'nt STLPort have the same restrictions as the MSVC implementation?
Sure you can:
Use this class as the allocator for whatever STL container you are using:
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.
#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.
Quote:Original post by antareus
I 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
It uses the heap that is allocated to the process, instead of the private ones used by the module's C runtime library.
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.
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:Original post by iMalc
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.
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<int>;" instantiates the STL stack class. The instantiation forces all members of class stack<int> 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
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<int>;" instantiates the STL stack class. The instantiation forces all members of class stack<int> 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.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement