Сборка .dll для более низкой версии visual studio - PullRequest
3 голосов
/ 07 июня 2011

Я использую Visual Studio 2010 для создания своей библиотеки DLL.

И другой программист, который использует Visual Studio 2005, хочет использовать мою библиотеку DLL.Он может скомпилировать с моей dll, но при запуске его приложения оно просто вылетает с исключением bad_alloc.Я предполагаю, что это из-за другой версии CRT.

При сборке библиотеки DLL я пробовал динамическое связывание CRT (/ MD) и статическое связывание CRT (/ MT), но оба не удалось.1006 * Итак, я не могу создать библиотеку DLL, которая может использоваться более низкой версией Visual Studio?Если нет, то как я могу это сделать?

Ответы [ 6 ]

3 голосов
/ 07 сентября 2011

Вы можете экспортировать только абстрактные базовые классы (содержащие хотя бы одну чисто виртуальную функцию) без элементов данных для двоичной совместимости, я думаю, что это было за вопросом о вашем прототипе dll. Здесь http://chadaustin.me/cppinterface.html - хорошее обсуждение вопроса.

3 голосов
/ 07 июня 2011

Самое простое решение: дать другому программисту исходный код вашей DLL и позволить ему скомпилировать DLL самостоятельно против старой CRT. Если это не подходит (потому что вы не хотите отдавать исходный код из ваших рук, или ваша DLL не компилируется с VC ++ 2005), вы должны либо получить компилятор VC ++ 2005, либо другой VC ++ 2010.

3 голосов
/ 07 июня 2011

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

и используйте следующий формат для ваших интерфейсов функций:

extern "C" __declspec(dllexport) void doSomething(int input);
2 голосов
/ 07 июня 2011

Если на вашем компьютере установлен VS2005, вы можете использовать новую функцию Platform Toolset VS2010 для использования компилятора VS2005.

Его значение Project Properties -> General -> Platform Toolset.VS100 - это vs2010, VS90 - на 2008 год и (я думаю) VS80 - это то, что вам нужно (на 2005 год ...).

AFAIK, пытаться использовать другую DLL, встроенную в набор инструментов, будет сложнее (хотя возможно, поскольку выне связывайтесь с ним).

Приветствия

1 голос
/ 07 июня 2011

Скорее всего, вы используете вещи (например, контейнеры или типы C ++), которые изменились между версиями реализаций компилятора VC ++, и передача их через границы DLL между библиотеками, созданными с разными версиями VC ++, скорее всего не удастся.

Вам нужно собрать DLL с этим конкретным компилятором (VC ++ 8.0 для VS2005, VC ++ 9.0 для 2008, VC ++ 10.0 для 2010 ...), чтобы другой программист мог использовать его. Это или он должен обновить свою Visual Studio, чтобы использовать ту же версию, что и у вас.

0 голосов
/ 31 октября 2011

Это довольно старая проблема, и это одна из причин COM. Я бы посоветовал вам сделать следующее -

  1. Создайте абстрактный базовый класс и (он же интерфейс) (скажем, IExportedFunctionality), который предоставляет методы, которые предлагает ваш в настоящее время экспортируемый класс (скажем, CExportedClass), и имеет виртуальный деструктор.
  2. Больше не экспортируйте CExportedClass.
  3. Получите класс CExportedClass из IExportedFunctionality и убедитесь, что все методы реализованы.
  4. Экспорт 2 функций из вашего Dll с именем

    a. GetExportedClass which returns a pointer to a new instance of CExportedClass upcast to IExportedFunctionality*.
    b. FreeExportedClass which accepts a IExportedFunctionality* and deletes it.
    

Теперь все, что вам нужно сделать, это предоставить заголовочный файл с объявлением IExportedFunctionality. Вы даже можете покончить с файлом lib, поскольку ваши пользователи могут использовать LoadLibrary и GetProcAddress для вызова GetExportedClass и FreeExportedClass.

Примечание: IExportedFunctionality должен иметь

  1. Только чисто виртуальные функции - поскольку IExportedFunctionality является интерфейсом, а не реализацией.
  2. Чистый виртуальный деструктор - так что выполнение удаления IExportedFunctionality * преобразуется в вызов деструктора CExportedClass
  3. Не иметь ЛЮБЫХ членов данных в IExportedFunctionality (как указал пользователь 383522, двоичная компоновка класса может варьироваться в зависимости от компилятора и при разных байтовых выравниваниях)
...