Nano Hash - криптовалюты, майнинг, программирование

Связывание DLL со статическими библиотеками

У нас есть исполняемый проект, который загружает файлы DLL во время выполнения в виде плагинов.

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

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

Можно ли сделать это?

Я пытался собрать все статические библиотеки в Visual Studio как статические библиотеки со средой выполнения, установленной на Многопоточность DLL с флагом /MD, но когда я пытаюсь собрать dynamiclibB.dll, я получаю ошибки компоновщика. Если я настрою dynamiclibB для сборки как статическую библиотеку, у нее не будет ошибок компоновщика.

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

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

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

Абсолютно все сейчас создается в режиме релиза, чтобы избежать этого осложнения.

Что мне не хватает?

Попытка диаграммы, которая может помочь понять ситуацию:

            program.exe
                |
         ________________
        |                |
  oldplugin.dll      newplugin.dll
        |                |
 dynamiclibA.dll     dynamiclibB.dll
                         |
            _________________________
           |             |           |
     staticlibA.lib   slibC.lib    slibD.lib   

Обновление: предоставление дополнительной информации теперь, когда я знаю, что происходит, и знаю, что более конкретные детали действительно важны. Таким образом, библиотека A, представленная dynamiclibA и staticlibA, была zlib. Библиотекой, которую мы компилировали (dynamiclibB) для использования в новом плагине, была PoDoFo. Сообщения об ошибках, которые мы получили, были:

Error   19  error LNK2001: unresolved external symbol
_deflateInit_   E:\Work\podofo_bin\src\PdfFiltersPrivate.obj    podofo_shared Error 20  error LNK2001: unresolved external symbol
_inflateEnd E:\Work\podofo_bin\src\PdfFiltersPrivate.obj    podofo_shared Error 21  error LNK2001: unresolved external symbol
_inflateEnd E:\Work\podofo_bin\src\libpng16.lib(pngread.obj)    podofo_shared Error 22  error LNK2001: unresolved external symbol
_deflate    E:\Work\podofo_bin\src\PdfFiltersPrivate.obj    podofo_shared Error 23  error LNK2001: unresolved external symbol
_deflate    E:\Work\podofo_bin\src\libpng16.lib(pngwutil.obj)   podofo_shared Error 24  error LNK2001: unresolved external symbol
_deflateEnd E:\Work\podofo_bin\src\PdfFiltersPrivate.obj    podofo_shared Error 25  error LNK2001: unresolved external symbol
_deflateEnd E:\Work\podofo_bin\src\libpng16.lib(pngwrite.obj)   podofo_shared Error 26  error LNK2001: unresolved external symbol
_inflateInit_   E:\Work\podofo_bin\src\PdfFiltersPrivate.obj    podofo_shared Error 27  error LNK2001: unresolved external symbol
_inflateInit_   E:\Work\podofo_bin\src\libpng16.lib(pngrutil.obj)   podofo_shared Error 28  error LNK2001: unresolved external symbol
_inflate    E:\Work\podofo_bin\src\PdfFiltersPrivate.obj    podofo_shared Error 29  error LNK2001: unresolved external symbol
_inflate    E:\Work\podofo_bin\src\libpng16.lib(pngrutil.obj)   podofo_shared

Остальное в ответ.


  • Вопросы: некоторые из этих зависимостей — это одна и та же библиотека, но разные версии, на которые ссылаются другие плагины — это означает, что old/newplugin.dll — это просто разные версии, верно? Это также относится к dynamiclibA/B.dll? Если да, то могу ли я предположить, что старые+A и новые+B пары были созданы с разными версиями MSVC? Кроме того, какие ошибки компоновщика вы получаете для dynamiclibB? 22.01.2015
  • Старые и новые плагины — это совершенно не связанные между собой плагины, которые в конечном итоге имеют одни и те же зависимости. 22.01.2015
  • Все это msvc10 22.01.2015
  • DynamiclibA и staticlibA — это одна и та же библиотека в разных версиях. На данный момент на телефоне, поэтому ошибки не могу получить до завтра, но они исчезают, когда я переключаю вывод b на .Lib, даже если я не меняю время выполнения (все / MD) 22.01.2015
  • Я добавил ваш вопрос в закладки, поэтому всякий раз, когда возникают ошибки ссылки, SO будет пинговать меня. Спасибо за диаграмму ASCII-art, кстати. 22.01.2015
  • Спасибо, но я скопировал это из другого похожего вопроса: p 22.01.2015
  • Плечи великанов и все такое 22.01.2015
  • Я могу дать немного больше информации по памяти, на самом деле существует несколько библиотек, которые подходят для ситуации, представленной библиотекой a, но сейчас речь идет о zlib. Ошибки компоновщика, iirc, заключаются в том, что все экспортированные функции из zlib не могут быть найдены при компоновке из динамической библиотеки b. Как я уже сказал, ошибки ссылок исчезают при сборке b как статической библиотеки, несмотря на наличие /MD. Насколько я понимаю, dll по сравнению со статической библиотекой на самом деле ничего не изменили, кроме того, где фактически хранится двоичный файл, когда время выполнения остается прежним. Должно быть, я ошибаюсь, но где правда? 22.01.2015

Ответы:


1

В моем вопросе slibc.lib был libpng. Libpng также требует zlib, но он создает его из исходного кода внутри своего решения. Мы смогли использовать выходные данные этого проекта так, как хотели, например, zlib.lib, созданную с флагом /MD, без ошибок компоновки.

Нам также удалось выяснить, почему возникла эта проблема: очень актуален другой вопрос stackoverflow: https://stackoverflow.com/a/6559315/78823

Оказывается, у zlib есть #define ZLIB_WINAPI, который определяет соглашение о вызовах как STDCALL, чего я не понимаю, но это вызывает ошибки компоновщика. Другой ответ предлагает удалить определение, и я полагаю, что это то, что libpng сделал со своим проектом zlib.

Я предполагаю, что причина, по которой ошибки компоновщика возникали только при сборке .dll и исчезали при сборке .lib, заключается в том, что (поправьте меня, если я ошибаюсь, я не совсем понимаю это), сборка .lib не на самом деле не делал ссылку на необходимые функции, поэтому просто передавал ошибки компоновщика на следующий уровень; Я думаю, мы увидели бы те же ошибки (но, возможно, в разных объектах/проектах) при компиляции newplugin.dll, но мы не продвинулись достаточно далеко, чтобы проверить это, прежде чем мы попробовали другие вещи.

22.01.2015
  • Ваша догадка верна. .lib едва ли сложнее, чем zip-файл из составляющих файлов .obj (у него также есть глобальный каталог, отображающий с именем exports имя содержащего его .obj). Библиотека .lib не связывается с внешними компонентами, от которых зависит ее составной код, и, поскольку компоновщик может выбрать использование только подмножества элементов ,obj, набор требуемых символов может варьироваться. 23.01.2015
  • Вы действительно решили проблему, и вам удалось статически связать libA с вашей libB.dll? Очень любопытно, потому что я хотел бы сделать то же самое 10.06.2020
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

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

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..