2017-02-21 10 views
1

Недавно я использовал библиотеку Assimp для моего проекта 3D-графики для хобби, чтобы загрузить 3D-модели.Почему динамическая библиотека C++ с интерфейсом C++ совместима между несколькими версиями компилятора - нет проблемы с проблемой ABI?

Библиотека поставляется в виде DLL в сопровождении библиотеки импорта - LIB - и файл EXP (только тогда, когда здание из последних источников, я понимаю, что содержит информацию об экспортируемых функциях, похожей на LIB)

Теперь - неожиданная часть, которая заставило меня вызвать этот вопрос, заключается в следующем:

Я был в состоянии правильно, без ошибок сборки/ссылки или ошибок во время выполнения использовать интерфейс C++ двух разных версий библиотека:

  • пр. e-built library - release 3.1.1, которая была построена и зависит от более старой версии (MSVCP110.DLL, MSVCR110.DLL) (позже я решил перейти на мою собственную сборку, так как в этой бинарной сборке произошла ошибка связывания)
  • Мой собственный источник билд с компилятором в VS 2013 (в зависимости от MSVCP120.DLL и VCRUNTIME120.DLL)

Я был в состоянии использовать оба эти библиотеки строят из моего исполняемого двоичного файла, и когда я построил EXE с VS 2013 компилятор и при построении с VS 2015 компилятор (который я также установил на том же компьютере)! Я внимательно проверил набор инструментов платформы.

Мое удивление успеха с помощью библиотеки, как описано выше, - без каких-либо Erorr, вызвано:

  • Я прочитал все через Интернет - несколько источников - о том, как C++ библиотеки и интерфейсы не являются бинарный, совместимый между различными версиями компилятора, и поэтому не может использоваться вместе с двоичными файлами, созданными с другими компиляторами, если они не являются COM-библиотеками, поэтому вы используете их через интерфейсы COM (которые предназначены для устранения этой проблемы) или через интерфейс C, который также обеспечивает совместимость с ABI.
  • Использование двоичных файлов, созданных с использованием разных компиляторов, может вызвать проблемы из-за следующего: в моем понимании: имя функции mangling (может быть решена библиотекой импорта!), Распределение и выделение динамической памяти, выполняемое разными версиями распределителей/деструкторов ,

Может ли кто-нибудь дать некоторое представление об этом прецеденте - почему я успешно смогла использовать встроенную динамическую библиотеку VS 2013 вместе с приложением VS 2015 для инструментов - без каких-либо из вышеперечисленных проблем? Кроме того, то же самое относится и к использованию предварительно построенных двоичных файлов, как с сборкой VS 2013, так и с VS 2015 для моего приложения 3D-движка. Это изолированный случай или сама библиотека Assimp заботится о проблемах и реализована таким образом, чтобы обеспечить совместимость?

Фактическое использование библиотеки было довольно простым: я использовал локальную переменную стека объекта (объекта) импортера, а оттуда - манипулировать и читать информацию из группы структур - никаких других классов (я думаю)

ответ

1

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

Даже использование строки std: не допускается через границы DLL, если модули используют разные компиляторы или даже имеют другое использование CRT или, по крайней мере, другой CRT.

Фактически, использование простых интерфейсов (чистых виртуальных классов) безопасно для всех компиляторов VS C++. Также использование extern «C» безопасно.

Итак, если структуры, которые вы обмениваете, представляют собой просто POD или имеют простые объекты данных с данными, и до тех пор, пока распределение и уничтожение выполняются внутри DLL, вы можете смешивать и использовать библиотеки DLL с разными компиляторами.

Таким образом, лучшими примерами являются DLL-файлы ОС Windows. Они используют четко определенный интерфейс простых структур данных. Управление и распределение памяти (например, окна, меню, объекты GDI) осуществляется с помощью прозрачного дескриптора. DLL - это только черные ящики для вас.

Надеюсь, что я встретил все точки.

+0

Я не имел в виду использование чистого интерфейса, но тот факт, что я использовал классы C++ для своих целей, хотя библиотека также предоставляет интерфейс C (функции extern C). Я объявил конкретную переменную стека Assimp :: Importer и использовал ее для чтения различных структур, к которым обращались указатели - aiScene, aiMesh, aiMaterial, aiPath, aiString и т. Д. Здесь перечислены: https://github.com/assimp/assimp/ tree/master/include/assimp –

+0

С VS-2010 до 2017 это должно работать, когда выделение и освобождение памяти выполняется только внутри DLL. и, как я вижу, новые и удаленные (все распределители) переопределяются. Таким образом, это должно работать, даже если используются различные ЭЛТ. Во всяком случае вы столкнетесь с внезапным сбоем, если для распределения и освобождения памяти используются разные ЭЛТ. Специально в режиме отладки. – xMRi

+0

В моем случае я использую только локальную переменную одного из типов классов, предоставляемых библиотекой, поэтому никакого динамического распределения через new не выделяется, и я также не освобождаю память, которую код библиотеки возвращает мне через указатели. Поэтому я думаю, что это причина, по которой я в безопасности, чтобы использовать ее и не сталкивался с какими-либо проблемами? Я полагаю, что все данные, которые даются через указатели, освобождаются в библиотечной DLL, когда мой объект выходит из области действия, и его деструктор вызывается. –

Смежные вопросы