STL-Klasse aus DLL exportieren - Warum wird vom Rückgabetyp keine Warnung ausgegeben?

Meine Frage bezieht sich auf das Exportieren einer C ++ - Klasse mit STL. Zum Beispiel:

class __declspec(dllexport) Hello
{
    std::string   name;

public:
    std::string&  getName();
    void          setName(const std::string& name);
}

Verschiedene Artikel scheinen darauf hinzuweisen, dass dies der Fall istsehr schlecht, was durchaus verständlich ist. Alles muss mit denselben Compilereinstellungen und derselben CRT-Version kompiliert werden. Sonst stürzt alles ab und brennt.

Frage:

Was ich nicht verstehe, ist, warum nur Datenmitglieder ein Problem zu haben scheinen. Mit dem folgenden Code erhalte ich: "C4251: Muss über eine DLL-Schnittstelle verfügen, um von Clients der Klasse verwendet zu werden"; was anscheinend durch den Export der instanziierten std :: string behoben wird:

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
}

Und die feste Version ist:

// 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!
}

(Dies gibt LNK2005 "basic_string already defined", wenn Sie versuchen, die DLL zu verwenden, was bedeutet, dass Sie die CRT auf dem Client nicht verknüpfen müssen, sodass die Instanziierung in der DLL verwendet wird.)

Rückgabetypen und Argumente scheinen kein Problem mit der STL zu haben und erhalten nicht die gleichen Behandlungsdaten, die Mitglieder vom Compiler erhalten.

// No exporting required?
struct __declspec(dllexport) SomeOtherClass
{
    std::string  doSomething1();                       // No problemo
    void         doSomething2(const std::string& s);   // No problemo
}
Zusätzliche Info (Frage ist oben)

Sowohl:

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;
}

Weder scheinen std :: basic_string noch std :: allocator zu exportieren. Sie exportieren vielmehr nur die Member / Funktionen der Klasse.

DieFest Die in der Frage erwähnte Version exportiert sowohl basic_string als auch allocator.

Antworten auf die Frage(2)

Ihre Antwort auf die Frage