Я знаю, что этот вопрос неоднократно задавался много раз, но я не уверен, что полностью понял концепции, которые здесь есть. В настоящее время я работаю над чем-то маленьким, как небольшим учебным проектом (так как я перестал использовать C++ некоторое время назад и хочу вернуться к нему), и из того, что я прочитал, есть несколько проблем при использовании STL в DLL.
Однако из того, что я собрал, есть два способа избежать возможных проблем.
Способ 1. Пользователи библиотеки DLL должны иметь один и тот же компилятор и такую же библиотеку времени выполнения C.
Способ 2. Скрыть всех членов класса STL от прямого доступа.
Однако, когда дело доходит до метода 2, я знаю, что член класса STL не может получить доступ непосредственно клиентом, чтобы этот метод работал, но означает ли это:
//Note all the code in this example was written directly in my web broswer with no checking.
#ifdef SAMPLEDLL_EXPORTS
#define SAMPLE_API __declspec(dllexport)
#else
#define SAMPLE_API __declspec(dllimport)
#endif
class SAMPLE_API SampleClass
{
std::map<int, std::string> myMap;
public:
SampleClass();
~SampleClass();
void addSomething(int in_Key, char* in_Val)
{
std::string s(in_Val);
myMap.insert( std::pair<int, std::string>(in_Key, s) );
};
bool getHasKey(int in_Key)
{
return myMap.find(in_Key) != myMap.end();
};
};
должно сработать?
Как отметил Ханс Пассант в комментарии, ваш пример немного сомнителен, потому что вы ввели все определения методов inline. Но предположим, что вы переместите определения в отдельный.cpp файл, который затем вы встраиваете в DLL.
Это не будет безопасно.
С самого начала мы имеем следующее:
class SAMPLE_API SampleClass
{
std::map<int, std::string> myMap;
Мне не нужно было смотреть дальше, потому что мы сразу видим, что размер SampleClass зависит от размера std :: map и не указывается стандартом. Поэтому, хотя вы можете сказать, что SampleClass не "раскрывает" свою карту, на самом деле это происходит. Вы можете использовать технику Pimpl, чтобы преодолеть это и по-настоящему скрыть карту от ABI вашего класса.