Jump to content
  • Advertisement
Sign in to follow this  

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.

If you intended to correct an error in the post then please contact us.

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 this post


Link to post
Share on other sites
Advertisement
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 this post


Link to post
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 this post


Link to post
Share on other sites
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

Share this post


Link to post
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 this post


Link to post
Share on other sites
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

Share this post


Link to post
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<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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!