Потенциальные риски памяти при связывании статически построенной библиотеки с общей библиотекой с использованием Visual Studio - PullRequest
0 голосов
/ 25 февраля 2012

Я работаю над кроссплатформенным плагином Firebreath, который вылетает в Windows. Я использую статическую библиотеку, содержащую классы, которые ссылаются на boost.asio. Когда я связываю эту библиотеку с плагином dll, я наблюдаю сбои при взаимодействии с подсистемой io_service (т. Е. Во время создания сокета). Когда я связываю статическую библиотеку с обычным исполняемым файлом, возникает проблема , а не . Когда я собираю содержимое статической библиотеки непосредственно в проект плагина dll, происходит сбой , а не . Я сделал все возможное, чтобы обеспечить согласованность всех аспектов моей среды сборки в Windows (режимы сборки, версия Visual Studio и т. Д.). Кроме того, я включил заголовок boost.asio, чтобы код dll плагина не отображал подсистему boost.asio (к сожалению, vs2008 и vs2010, к сожалению, безрезультатно). Насколько я могу судить, я сделал все возможное, чтобы обеспечить хорошее поведение среды сборки, но проблема сохраняется.

Может ли сообщество предложить какой-либо совет относительно потенциальных рисков или подходов, которые могут выявить или решить проблему?

Ответы [ 2 ]

1 голос
/ 25 февраля 2012

Две вещи, которые существенно отличаются между связыванием статической библиотеки и загрузкой DLL:

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

  • shared CRT: в статической библиотеке все вызовы стандартной библиотеки разрешаются во время соединения, и все основное приложение и библиотечная функция вызывают одну и ту же копию стандартной библиотеки.В DLL вы рискуете получить две копии стандартной библиотеки, что может быть хорошо, если вы не будете делиться какими-либо объектами стандартной библиотеки (такими как FILE*, std::string или даже malloc / free пары) между библиотекой и приложением.

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

Преимущество «лучшего» способа заключается в том, что плагины могут быть встроены в любую версию компилятора, что становится большой проблемой для сопровождения в дальнейшем в цикле разработки.

0 голосов
/ 21 мая 2012

В сценарии подготовки плагина FireBreath, попробуйте , включив флаг WITH_DYNAMIC_MSVC_RUNTIME .

...