Как я могу передать объекты C ++ в библиотеки DLL с разными _ITERATOR_DEBUG_LEVEL - PullRequest
1 голос
/ 17 марта 2011

Мой исполняемый файл выполняет вызовы ряда DLL, которые я написал сам.Согласно сторонним библиотекам C ++, используемым этими библиотеками, я не могу свободно выбирать настройки компилятора для всех библиотек DLL.Поэтому в некоторых библиотеках _ITERATOR_DEBUG_LEVEL установлен на 2 (по умолчанию в отладочной версии), но в моем исполняемом файле _ITERATOR_DEBUG_LEVEL установлен на 0, в соответствии с серьезными проблемами производительности.* в DLL приложение вылетает, как только DLL пытается скопировать его в локальный std :: string obj, поскольку структура памяти строкового объекта в DLL отличается от той, что в моем исполняемом файлеПока я работаю над этим, передавая C-струны.Я даже написал небольшой класс, который преобразует std::map<std::string, int> во временное представление в C-Data и из него для передачи sich-данных из и в DLL.Это работает.

Как я могу преодолеть эту проблему?Я хочу передать больше разных классов и контейнеров, и по нескольким причинам я не хочу работать с _ITERATOR_DEBUG_LEVEL = 2.

Ответы [ 3 ]

3 голосов
/ 17 марта 2011

Не рекомендуется использовать интерфейс c ++ со сложными типами (stl ...) с сторонними библиотеками, если вы получаете их только в двоичном виде или вам нужны специальные настройки для компиляции, которые отличаются от ваших настроек.

Как вы писали - реализация может отличаться для одного и того же компилятора в зависимости от ваших настроек, а для разных компиляторов ситуация становится еще хуже.

Если возможно, скомпилируйте стороннюю библиотеку с вашим компилятором и вашими настройками.

Если это невозможно, вы можете написать DLL-оболочку, которая компилируется с тем же компилятором и теми же настройками, что и сторонняя библиотека, и предоставляет вам интерфейс C-Data. В вашем проекте вы можете написать еще один класс-обертку, чтобы вы могли выполнять вызовы функций с помощью объектов STL и преобразовывать их и передавать «в фоновом режиме».

2 голосов
/ 17 марта 2011

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

Чтобы исправить это, у вас есть несколько решений, но все они следуют одному и тому же правилу: не раскрывайте никакого кода шаблона в общем коде вашего заголовкамежду двоичными файлами .

Вы можете создать определенные интерфейсы только для этой цели или просто убедиться, что ваши заголовки не предоставляют типы шаблонов и функции.Вы можете использовать эти типы шаблонов в своих двоичных файлах, но не открывайте их другим двоичным файлам.

std :: string в интерфейсах можно заменить на const char *.Вы все еще можете использовать std :: string в своих системах, просто запросите const char * в интерфейсах и используйте std :: string :: c_str () для предоставления ваших данных.

Для карт и других контейнеров выдолжны предоставлять функции, которые позволяют внешнему коду манипулировать внутренней картой.Как "Найти (const char * key);".

Основная проблема будет с членами шаблона ваших открытых классов.Чтобы это исправить, используйте идиому PImpl: создайте (или сгенерируйте) API, заголовки, которые просто показывают, что можно сделать с вашими двоичными файлами, а затем убедитесь, что у API есть указатели на реальные объекты внутри ваших двоичных файлов.API будет использоваться снаружи, но внутри вашей библиотеки вы можете кодировать что угодно.DirectX API и другие OS API сделаны таким образом.

2 голосов
/ 17 марта 2011

Мой собственный опыт работы с флагами, такими как _SECURE_SCL и _ITERATOR_DEBUG_LEVEL, заключается в том, что они должны быть согласованы, если вы пытаетесь передать объект stl через библиотеки dll.Однако я думаю, что вы можете передать объект stl в dll, которая имеет меньший _ITERATOR_DEBUG_LEVEL, так как вы, вероятно, можете передать объект stl, созданный в отладочной dll, в dll, скомпилированную в режиме выпуска.

EDIT 07/04/2011Очевидно, Visual Studio 2010 предоставляет некоторые тонкости для обнаружения несоответствий между ITERATOR_DEBUG_LEVEL.Я еще не смотрел видео.

http://blogs.msdn.com/b/vcblog/archive/2011/04/05/10150198.aspx

...