Exportando a classe STL da DLL - por que não há aviso do tipo de retorno?
Minha pergunta está relacionada à exportação de uma classe C ++ com STL dentro. Por exemplo:
class __declspec(dllexport) Hello
{
std::string name;
public:
std::string& getName();
void setName(const std::string& name);
}
Vários artigos parecem indicar que isso émuito mal, o que é bastante compreensível. Tudo deve ser compilado com as mesmas configurações do compilador e versão CRT. Caso contrário, tudo irá falhar e queimar.
Questão:O que não entendo é por que apenas membros de dados parecem ter um problema. Com o código abaixo, eu recebo: "C4251: precisa ter interface dll para ser usada pelos clientes da classe"; que aparentemente é corrigido exportando o std :: string instanciado:
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
}
E a versão fixa é:
// 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!
}
(Isso dará ao LNK2005 "basic_string já definido" quando você tentar usar a DLL, o que significa que você não precisa vincular o CRT ao cliente - assim, ele acaba usando a instanciação na DLL).
Os tipos e argumentos de retorno parecem não ter problemas com o STL e não recebem os mesmos dados de tratamento que os membros obtêm do compilador.
// No exporting required?
struct __declspec(dllexport) SomeOtherClass
{
std::string doSomething1(); // No problemo
void doSomething2(const std::string& s); // No problemo
}
Informações Adicionais (a pergunta está acima)Em ambos:
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;
}
Nem parece exportar std :: basic_string ou std :: allocator. Em vez disso, eles exportam apenas os membros / funções da classe.
No entanto, ofixo A versão mencionada na questão exporta basic_string e allocator.