Sign in to follow this  
ProgrammerZ

Making a DLL . . . Am I doing this right?

Recommended Posts

Okay. So about a week ago, I decided to try and compile my engine into a DLL that I could use in future projects. Problem? I didn't know how. So, after looking around on the internet and Gamedev.net for a while, I figured out a basic understanding of DLLs. Here is a list of things I have done so far (I am using MSVC++): 1. I made a copy of my engine project and set the configuration type to DLL. 2. I put __declspec(dllexport) before all of my class declarations. 3. I removed the C++ file with my WinMain function in it. 4. I built the project and got a LIB, DLL, and EXP file. What I plan to do: 1. Copy all the header files in my engine project to my game project folder. 2. Copy my LIB and DLL files from my engine project to my game project folder. 3. #include my header files into my game files that use them. 4. Link my game project to my LIB file. Concerns/questions: 1. I got this warning when I built my project:
warning C4251: 'IResourceSystem<T>::m_AvaliableHandles' : class 'std::stack<_Ty>' needs to have dll-interface to be used by clients of class 'IResourceSystem<T>'

IResourceSystem is a resource manager class. It owns a stack of integers that stores any avaliable resource handles. Do I need to worry about this warning? Thanks in advance! -- ProgrammerZ

Share this post


Link to post
Share on other sites
According to this website

http://www.unknownroad.com/rtfm/VisualStudio/warningC4251.html

It would seem you have a problem with IResourceSystem<T> not being exported as it is a declaration. But you are creating IResourceSystem<int> and the compiler gets a bit confused finding the template declaration.

You can put a forward explicit instantiation of IResourceSystem<int> which should fix it.

The above website should explain it all better than me.

Share this post


Link to post
Share on other sites
Quote:
IResourceSystem is a resource manager class. It owns a stack of integers that stores any avaliable resource handles. Do I need to worry about this warning?


yes. std::stack, it's allocators and other classes exposes by it's interface are not exported as part of the dll. This means that if someone used your engine dll, with say, STL port, the structures will no longer be compatible, and will crash. (As a test, try linking a release App against a debug DLL, and exactly the same thing will happen...)

As a general rule, don't use STL anywhere in your DLL interfaces. i.e.

// don't inherit from STL
class EXPORT Blah : public std::stack<int>
{
public:

// or use it in function definitions.
std::string getName();
}


prefer this:


class EXPORT Blah
{
public:

// now just expose the std::stack funcs you need...
int top() { return mInternal.top(); }
void push(int i) { mInternal.push(i); }
int pop() { return mInternal.pop(); }

// or use it in function definitions.
const char* getName();

private:

std::stack<int> mInternal;
}


As a general rule, I hate templates that form part of the DLL interface, mainly because you never really know what gets compiled into the DLL, and what ends up being duplicated code in the projects that depend on that. For example, IResourceSystem<T> is a template. Templates can't be embedded into DLL's, they have to be compiled inline. So, where does the compiled code for these templates exist?

IResourceSystem<Sound>
IResourceSystem<LevelFile>
IResourceSystem<ReplayDataFile>
IResourceSystem<Music>
IResourceSystem<Texture>
IResourceSystem<Model>

Anyhow, you can make the warning go away, but it's a pointless waste of time imho, since you'll need different versions for VC2003, VC2005, VC2008, gcc, STLport1,2,3,4, etc. The sheer number of permutations you need, is a bit prohibitive.

Share this post


Link to post
Share on other sites
Quote:
Original post by theZapper
You can put a forward explicit instantiation of IResourceSystem<int> which should fix it.


The author of that article has miss understood the subtleties, the compiler isn't confused at all. An explicit instantiation of IResourceSystem<int> won't fix the problem either.

The only way to solve this problem is to export every single template class that is used in the interface for IResourceSystem<int>. That means,


stack<int, deque<int, allocator<int> > >
deque<int, allocator<int> >
allocator<int>
deque<int, allocator<int> >::iterator
deque<int, allocator<int> >::const_iterator
deque<int, allocator<int> >::reverse_iterator
deque<int, allocator<int> >::const_reverse_iterator


AND, every single operator and/or function that is defined outside of the class that uses any of the above templates. That needs to be repeated for every single specialisation of IResourceSystem<T>.

Share this post


Link to post
Share on other sites
Thanks for all the replies, guys! I just a couple of questions: how do I export those classes? I googled it, but I didn't get anything relevant. Also, I saw on one of those sites that it's impossible to export any stl containers except for the std::vector. Is that site outdated?

Share this post


Link to post
Share on other sites
Although it's avoiding the question somewhat, I'd recommend using an interface where possible, I.e. only have the user of the DLL know about a class with nothing but pure virtual functions in it, and a factory function. The DLL can then derive from that pure virtual class and return an instance of the dericved class from the factory function.
That way users of the DLL won't need to worry about your STL version or the various other problems.

Unfortunately, that won't work with templates though, so it might not really be that useful...

Share this post


Link to post
Share on other sites
Quote:
Original post by ProgrammerZ
Thanks for all the replies, guys! I just a couple of questions: how do I export those classes? I googled it, but I didn't get anything relevant. Also, I saw on one of those sites that it's impossible to export any stl containers except for the std::vector. Is that site outdated?


1. Don't bother
2. Depends which compiler and which implementation of STL you are using. Which is the reason for answer 1.

I'd suggest either disabling the warning, or re-write your dll interfaces to remove STL from them.

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