Использование STL в библиотеке с закрытым исходным кодом - PullRequest
8 голосов
/ 31 августа 2010

Безопасно ли использовать один стандартный совместимый STL в библиотеке, а другой - в проекте, который использует эту библиотеку?Например:

//library.h

#include <string>  //let's say here it uses minGW STL

void Foo(std::string& str_mingw);

//library.cpp
void Foo(std::string& str_mingw) { /*do something*/ }



//application.cpp

#include "library.h"
#include <string>  //let's say here it uses VStudio STL

void Bar()
{
  std::string str_vstudio;
  Foo(str_vstudio);
  //Foo() inside the .lib or .dll uses string from minGW,
  //but here a string from VStudio is used
}

Мне кажется, что случится что-то плохое, особенно если используется не простая строка, а нечто более сложное, например tr2 :: thread.Но если это так, как я могу скомпилировать библиотеку в одном компиляторе и позволить пользователям библиотеки свободно выбирать предпочтительный компилятор для своих проектов?

Ответы [ 4 ]

6 голосов
/ 31 августа 2010

Безопасно ли использовать один стандартный совместимый STL в библиотеке, а другой - в проекте, который использует эту библиотеку?

Нет.

Некоторые части STLдля повторного использования помещаются в общую библиотеку.Невозможно гарантировать, что внутренняя структура классов будет совпадать в разных STL, что приведет к спорадическим сбоям, если оба будут использоваться программой взаимозаменяемо.

Также обратите внимание, что STL разных поставщиков могут иметь разную организацию внутреннихпространства имен и классы.Это приводит к тому, что открытый символ std::basic_string может иметь разные внутренние имена и будет искажаться по-разному, делая void Foo(std::string& str_mingw); и void Foo(std::string& str_vstudio); с точки зрения компоновщика двумя разными функциями.

6 голосов
/ 31 августа 2010

Если - под библиотекой - вы имеете в виду динамическую библиотеку - простой ответ: нет, а сложный ответ: нет.

C ++ и динамические библиотеки - это ОЧЕНЬ хрупкая перспектива. Любое небольшое изменение требует перестройки всех модулей, и время выполнения, используемое каждой библиотекой, ДОЛЖНО быть точно таким же экземпляром библиотеки.

Даже если вам удалось получить std :: string через границу dll - хотя внешний интерфейс std :: string фиксирован, любые различия в реализации приведут к повреждению данных.

Передавать простые структуры POD и собственные типы данных между динамическими библиотеками безопасно только в том случае, если среды выполнения потенциально различны - и даже в этом случае необходимо соблюдать осторожность для правильного управления временем жизни объектов - библиотека-распределитель ДОЛЖНА быть библиотекой-распределителем.

Если вы имеете в виду статическую библиотеку - это не имеет большого смысла - я не думаю, что библиотеки, созданные MinGW, будут совместимы с MSDev, а библиотеки MSDev несовместимы с MinGW. Даже если формат файла lib будет номинально совместим - если предположить, что различные искажения имен не помешают успешному линлингу: будет использоваться библиотека STL конечной среды компоновки.

4 голосов
/ 31 августа 2010

Это зависит от библиотеки, платформы и того, как вы ее компилируете и связываете.Часто библиотеки (особенно в Windows) распространяются как библиотеки DLL, и существуют очень конкретные правила относительно того, что может быть на границах, и как каждая из них должна быть скомпилирована.

Например, Boost создает библиотеки DLL для:

  • одиночная или многопоточная
  • отладка или выпуск
  • статическая (lib) или динамическая (DLL)
  • для каждого отдельного компилятора и версии

См. http://beta.boost.org/doc/libs/1_36_0/more/getting_started/windows.html#library-naming для перестановок.

Так что да, это большая проблема.

1 голос
/ 31 августа 2010

Безопасно ли использовать один стандартный совместимый STL в библиотеке, а другой - в проекте, который использует эту библиотеку?... void Foo(std::string& str_mingw); ... Foo(str_vstudio);

Нет.Это даже не имеет ничего общего с динамическими библиотеками.Даже если вам удастся каким-то образом связать и MS std :: string, и MinGW std :: string в одном исполняемом файле, он все равно сломается.У вас есть два отдельных (вероятно, разных) определения std :: string в вашей программе, и если вы смешаете их, вы окажетесь в неопределенном поведении land.

Обратите внимание, что это будет работать, если ваш std :: string неиспользуется в интерфейсе.То есть: у вас может быть одна библиотека, которая использует строки MinGW внутри, и другая библиотека, которая использует строки VC внутри, если вы используете const char * (в качестве примера) на уровне интерфейса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...