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.