Экспорт класса STL из DLL - почему нет предупреждения от возвращаемого типа?
Мой вопрос связан с экспортом класса C ++ с STL внутри. Например:
class __declspec(dllexport) Hello
{
std::string name;
public:
std::string& getName();
void setName(const std::string& name);
}
Различные статьи, кажется, указывают, что этоочень плохо, что вполне понятно. Все должно быть скомпилировано с теми же настройками компилятора и версией CRT. Иначе все рухнет и сгорит.
Вопрос:Чего я не понимаю, так это того, почему проблема возникает только у членов данных. С кодом ниже я получаю:C4251: должен иметь dll-интерфейс для использования клиентами класса"; что, по-видимому, исправлено путем экспорта экземпляра 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
}
И исправленная версия:
// 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!
}
(Это даст LNK2005 «basic_string уже определено», когда вы попытаетесь использовать DLL, что означает, что вы не должны ссылаться в CRT на клиенте - так что в конечном итоге он использует инстанцирование в DLL).
Типы возвращаемых данных и аргументы, по-видимому, не имеют проблем с STL и не получают те же данные обработки, которые получают члены от компилятора.
// No exporting required?
struct __declspec(dllexport) SomeOtherClass
{
std::string doSomething1(); // No problemo
void doSomething2(const std::string& s); // No problemo
}
Дополнительная информация (вопрос выше)В обоих:
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;
}
Похоже, ни один из них не экспортирует std :: basic_string или std :: allocator. Скорее они экспортируют только члены / функции класса.
Однакоисправлено Версия, упомянутая в вопросе, экспортирует как basic_string, так и allocator.