Вызывающие функции с параметрами STL из общей библиотеки

Я знаю, что невозможно безопасно экспортировать параметры функции С++ (например, строки STL), потому что С++ не указывает стандартный ABI. (Я прочитал это как ответ Как вызвать функцию из общей библиотеки?)

Люди склонны полагать, что если и ваша библиотека, и ваша программа были построены с одним и тем же компилятором, это не проблема, но, к сожалению, для некоторых компиляторов VС++ это не совсем так.

Herb Sutter и Alexandrescu в "Стандартах кодирования С++" предлагают полагаться на переносные типы (например, встроенные типы) вместо функции, которая принимает string.

т.е. вместо использования std::string в интерфейсе модуля

 std::string Translate( const std::string & );

используйте

void Translate( const char *src, char* dest, size_t destSize );

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

Как можно передать более сложный объект, например std::map, используя типы низкого уровня? (не говоря уже о сложном, как map<string,vector<something_complex> >)

Как вы решаете такие случаи при экспорте функций?

Ответ 1

Не только вы должны создать программу, используя тот же самый компилятор (или совместимый ABI), вы должны использовать те же настройки: режим отладки и выпуска, DLL и статический режим, проверенные итераторы (или нет) и скоро. В некотором отношении STLPort сделал это правильно: std::string при построении для своей библиотеки переименовывается в различные символы на основе этих параметров, избегая проблемы полностью.

Другой вариант - передать непрозрачные указатели на объекты, выделенные, размещенные и используемые в DLL. Фактически, создавая свой собственный виртуальный интерфейс для функций, которые вам нужны, если вы хотите использовать их как объекты вне библиотеки DLL.