OK, así que he leído varias preguntas y artículos sobre este tema, y siento que entiendo los conceptos básicos, pero sigo teniendo problemas .Al exportar la plantilla STL std :: basic_string desde DLL, recibo un error LNK2005
Tengo una DLL que exporta una clase que tiene std :: string como miembro. Mi programa principal contiene clases que también tienen cadenas y usa la DLL.
Si puedo compilar el archivo DLL en VS2010, consigo las siguientes advertencias:
warning C4251: 'MyClass::data' : class 'std::basic_string<_Elem,_Traits,_Ax>' needs to have dll-interface to be used by clients of class 'MyClass'
Cuando puedo compilar el EXE, consigo las mismas advertencias, pero no hay errores, y el programa compila y ejecuta. En realidad, es un proyecto grande, así que recibo 40 advertencias, y no estoy muy interesado en eso. (Como un lado-observación, estas advertencias no están presentes cuando se compila con VS2008)
Así, leí acerca de que la alerta, y me llevan a este artículo EM: http://support.microsoft.com/default.aspx?scid=KB;EN-US;168958 que le dice cómo exportar una plantilla STL desde una DLL para satisfacer las advertencias que recibía.
El problema es, cuando agrego las siguientes líneas para eliminar las advertencias:
EXPIMP_TEMPLATE template class DECLSPECIFIER std::allocator<char>;
EXPIMP_TEMPLATE template class DECLSPECIFIER std::basic_string< char, std::char_traits<char>, std::allocator<char> >;
la DLL compila sin advertencias, pero cuando compilo mi EXE, el enlazador le da un ataque:
2>SampleDLL.lib(SampleDLL.dll) : error LNK2005: "public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::~basic_string<char,struct std::char_traits<char>,class std::allocator<char> >(void)" ([email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@[email protected]) already defined in OtherClass.obj
2>SampleDLL.lib(SampleDLL.dll) : error LNK2005: "public: unsigned int __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::size(void)const " ([email protected][email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@QBEIXZ) already defined in OtherClass.obj
Tanto el DLL como el EXE se compilan con las mismas opciones de generación de código. Puedo usar MT en ambos o MD, y los resultados son los mismos.
Estoy incluyendo el código de un programa de muestra minimizado en caso de que haya dejado algo fuera.
Mi pregunta principal: ¿Puedo reparar los errores de LNK2005, o es seguro ignorar las advertencias de C4251?
Editar: Así que he leído un poco más, y parece que si el std :: string que utiliza la clase DLL es una variable privada que sólo se accede por funciones miembro, puede ser seguro ignora la advertencia ... ¿Algún comentario sobre esto? ¿Es este un paso en la dirección correcta?
código DLL:
#pragma once
#include <exception>
#include <string>
#ifdef SAMPLEDLL_EXPORTS
# define DECLSPECIFIER __declspec(dllexport)
# define EXPIMP_TEMPLATE
#else
# define DECLSPECIFIER __declspec(dllimport)
# define EXPIMP_TEMPLATE extern
#endif
//disable warnings on extern before template instantiation (per MS KB article)
#pragma warning (disable : 4231)
//std::basic_string depends on this allocator, so it must also be exported.
EXPIMP_TEMPLATE template class DECLSPECIFIER std::allocator<char>;
//std::string is a typedef, so you cannot export it. You must export std::basic_string
EXPIMP_TEMPLATE template class DECLSPECIFIER std::basic_string< char, std::char_traits<char>, std::allocator<char> >;
#pragma warning (default : 4231)
class DECLSPECIFIER MyClass
{
public:
std::string getData(); //returns 'data', body in CPP file
private:
std::string data;
int data2;
};
//in SampleDLL.cpp file...
std::string MyClass::getData() { return data; }
código EXE:
#include <iostream>
#include "SampleDLL.h"
using namespace std;
void main()
{
MyClass class1;
cout << class1.getData() << endl;
}
posible duplicado de [Exportación de clases que contienen std :: objetos (vector, mapa, etc.) desde un dll] (http: // stackoverflow.com/questions/767579/exporting-classes-containing-std-objects-vector-map-etc-from-a-dll) – Mark
Mark: Leí esa pregunta, pero no parecía tener una respuesta para el problema Estoy viendo porque no menciona el problema adicional de LNK2005 que ahora tengo. – JPhi1618