При экспорте шаблона STL std :: basic_string из DLL я получаю ошибку LNK2005

Хорошо, я прочитал несколько вопросов и статей по этой теме, и мне кажется, что я понимаю основы, но я м. все еще проблемы.

У меня есть библиотека DLL, которая экспортирует класс, членом которого является std :: string. Моя основная программа содержит классы, в которых также есть строки, и использует DLL.

Если я компилирую DLL в VS2010, я получаю следующие предупреждения:

warning C4251: 'MyClass::data' : class 'std::basic_string<_Elem,_Traits,_Ax>' needs to have dll-interface to be used by clients of class 'MyClass'

Когда я компилирую EXE, я получаю те же предупреждения, но ошибок нет, программа компилируется и запускается. На самом деле это большой проект, поэтому я получаю около 40 предупреждений, и мне это не очень нравится. (В качестве дополнительного замечания, эти предупреждения отсутствуют при компиляции с VS2008)

Итак, я прочитал об этом предупреждении, и оно привело меня к этой статье MS: http://support.microsoft.com/default.aspx?scid=KB;EN-US;168958 в котором рассказывается, как экспортировать шаблон STL из библиотеки DLL, чтобы удовлетворить получаемые мной предупреждения.

Проблема в том, что я добавляю следующие строки для удаления предупреждений:

EXPIMP_TEMPLATE template class DECLSPECIFIER std::allocator;
EXPIMP_TEMPLATE template class DECLSPECIFIER std::basic_string< char, std::char_traits, std::allocator >;

DLL компилируется без предупреждений, но когда я компилирую свой EXE-файл, компоновщик срабатывает:

2>SampleDLL.lib(SampleDLL.dll) : error LNK2005: "public: __thiscall std::basic_string,class std::allocator >::~basic_string,class std::allocator >(void)" (??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ) already defined in OtherClass.obj
2>SampleDLL.lib(SampleDLL.dll) : error LNK2005: "public: unsigned int __thiscall std::basic_string,class std::allocator >::size(void)const " (?size@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEIXZ) already defined in OtherClass.obj

И DLL, и EXE скомпилированы с теми же параметрами генерации кода. Я могу использовать МП на обоих или на MD, и результаты будут одинаковыми.

Я включаю код из свернутой программы-примера на тот случай, если я что-то пропустил выше.

Мой главный вопрос: могу ли я исправить ошибки LNK2005, или можно просто игнорировать предупреждения C4251?

Изменить: Итак, я прочитал немного больше, и похоже, что std: : строка, которую использует класс DLL, является частной переменной, к которой имеют доступ только функции-члены, можно безопасно игнорировать предупреждение ... Есть какие-либо комментарии по этому поводу? Это шаг в правильном направлении?

Код DLL:

#pragma once

#include 
#include 


#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;
//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, std::allocator >;
#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; }

EXE-код:

#include 
#include "SampleDLL.h"

using namespace std;

void main()
{
    MyClass class1;

    cout << class1.getData() << endl;

}

10
задан jeffm 23 January 2012 в 21:12
поделиться