http://support.microsoft.com/default.aspx?scid=kb;EN-US;168958
Bloody windoze... You have to force an explicit instantiation with a __declspec(dllexport) inside the dll, a __declspec(dllimport) when using the dll, and an "extern" in front of the template keyword when using the dll...
Might as well sacrifice a chicken to Bill while you're at it.
I'm not sure about mingw, I know Borland does automatically export because there is a commandline option to tell it to do so.
But if mingw wasn't exporting/importing, then iterating over a a vector full of strings returned from a method inside a dll wouldn't work, and it does.
No idea on other OSs, and don't really care, what I do care about is it working.
It wouldn't surprise me if it was re-compiling, but then throwing away the rendundant template instatiations. The whole shared library thing is much better on unixish platforms (though loading plugins is a little strange on MacOSX)- it defaults to every symbol in a .so file being exported by default, and whilst the ability to hide symbols is part of the ELF specification, it hasn't been properly supported by pre GCC 4.0 compilers (the only way you could hide something was by declaring it as static in a cpp file, or putting it in an anonymous namespace).
It hasn't mattered, on unixish platforms shared objects just work without hassle. No import libraries are needed either.
I think BeOS needed identical __declspec stuff to windows, but BeOS is dead.
Returning a std::vector from a DLL would still work even if the instantiated template code was not exported from the DLL. This would be because a copy of the code would be created inside the executable and another in the DLL, and all that would be passed would be the data that they use.
I wouldn't be too surprised if it did the same thing in shared libraries on unix platorms too. Because to you still need to compile against the library's header files when you want to use it. Therefore your code knows that it needs to instantiate a std::vector etc, and it would compile that code into the binary. I guess you'd have to inspect the symbols stored and the code generated for the shared library to be able to tell for sure.
The data types still have to be exported, and this is not a normal string (I know std::string is exported from msvcrt).
It is a std::basic_string, MyMetapoolAllocator > i.e. a string that uses an allocator that uses my memory pool system.
Even then this is a nebulous point: msvc throws out a million warning messages about returning vectors from a function in a dll, it says that it will not work.
I'll try removing my exports and running a test in msvc. Another test would be making a public map member variables in an exported class, and try using it in an exe.
Well templates are really generated at compile time, the compile time of where they are used to be more precise. Therefore in order to have a templated class of some sort (say std::vector) in a library of yours you need to tell it to generate the code for that class. Thus requiring an explicit instantiation, otherwise the template will be compiled when it gets actually used in some other program.