Eksportowanie klasy STL z biblioteki DLL - dlaczego nie ma ostrzeżenia z typu powrotu?

Moje pytanie dotyczy eksportowania klasy C ++ z STL wewnątrz. Na przykład:

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

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

Różne artykuły wydają się wskazywać, że tak jestbardzo źle, co jest całkiem zrozumiałe. Wszystko musi być skompilowane przy użyciu tych samych ustawień kompilatora i wersji CRT. W przeciwnym razie wszystko się zawiesza i pali.

Pytanie:

Nie rozumiem, dlaczego tylko członkowie danych wydają się mieć problem. Z poniższym kodem otrzymuję: „C4251: musi mieć interfejs dll do użycia przez klientów klasy„; który najwyraźniej został naprawiony przez eksportowanie 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
}

A poprawiona wersja to:

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

(To da LNK2005 „podstawowy łańcuch już zdefiniowany” podczas próby użycia biblioteki DLL, co oznacza, że ​​nie musisz łączyć się w CRT na kliencie - więc kończy się na użyciu instancji w bibliotece DLL).

Zwracane typy i argumenty wydają się nie mieć problemu z STL i nie otrzymują tych samych danych dotyczących leczenia otrzymywanych od kompilatora.

// No exporting required?
struct __declspec(dllexport) SomeOtherClass
{
    std::string  doSomething1();                       // No problemo
    void         doSomething2(const std::string& s);   // No problemo
}
Dodatkowe informacje (pytanie powyżej)

Zarówno:

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

Wydaje się, że nie eksportuje std :: basic_string ani std :: allocator. Zamiast tego eksportują tylko członków / funkcje klasy.

Jednakżenaprawiony Wersja wspomniana w pytaniu eksportuje zarówno basic_string, jak i allocator.

questionAnswers(2)

yourAnswerToTheQuestion