My question is related to exporting a C++ class with STL inside. For example:
class __declspec(dllexport) Hello
{
std::string name;
public:
std::string& getName();
void setName(const std::string& name);
}
Various articles seems to indicate that this is very bad, which is quite understandable. Everything must be compiled with the same compiler settings and CRT version. Otherwise everything will crash and burn.
Question:
What I don't understand is why only data members seem to have an issue. With the below code, I get: "C4251: needs to have dll-interface to be used by clients of class"; which is apparently fixed by exporting the instantiated std::string:
struct __declspec(dllexport) SomeClass
{
// Removes the warning?
// http://www.unknownroad.com/rtfm/VisualStudio/warningC4251.html
// template class __declspec(dllexport) std::string;
std::string name; // Compiler balks at this
}
And the fixed version is:
// Export the instantiations of allocator and basic_string
template class __declspec(dllexport) std::allocator<char>;
template class __declspec(dllexport) std::basic_string<char, std::char_traits<char>, std::allocator<char> >;
struct __declspec(dllexport) SomeClass
{
std::string name; // No more balking!
}
(This will give LNK2005 "basic_string already defined" when you try to use the DLL, meaning you have to not link in the CRT on the client - so it ends up using the instantiation in the DLL).
Return types and arguments seem to have no problem with the STL, and do not receive the same treatment data members get from the compiler.
// No exporting required?
struct __declspec(dllexport) SomeOtherClass
{
std::string doSomething1(); // No problemo
void doSomething2(const std::string& s); // No problemo
}
Additional Info (Question is above)
In both:
class A {
std::string foo() { return std::string(); }
// std::string& foo(); gives the same result!
// std::string* foo(); also gives the same result!
}
class B {
std::string a;
}
Neither seem to export std::basic_string or std::allocator. Rather, they only export the members/functions of the class.
However the fixed version mentioned in the question exports both basic_string and allocator.