Правильный способ связать статические библиотеки с DLL

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

С помощью __declspec(dllexport) Атрибут не приводит к появлению указанных функций статических библиотек в dll, библиотеки вообще не связаны с dll.

Затем я попытался собрать каждую библиотеку как общую для получения собственных имен экспортируемых функций и создал на их основе файл .def. Использование файла .def приводит к результату.

  1. Должен __declspec(dllexport) а также .def-file действовать одинаково в моем случае?

  2. Можно ли создать файл .def из источников? Поскольку у меня есть код на C ++, я не могу самостоятельно написать файл .def из-за искажения и классов присутствия в API, описанный выше подход с использованием временных сгенерированных dll несовместим с производством.

Обновить

Я хотел бы подробно объяснить структуру моего проекта. Решение состоит из нескольких проектов (модулей).

+
|
+-+ static_lib1
|       +
|       +--+ src
|
+-+ static_lib2
|       +
|       +--+ src
|
+-+ dynamic_lib (linked with static_lib1 and static_lib2)
+
+--+ src

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

11

Решение

Статические библиотеки не должны содержать никаких __declspec или же __attribute((dll...)) вещи. Это не более чем несколько объектных файлов (обычно *.obj или же *.o), составленный в один файл.

Все, что вам нужно сделать, чтобы использовать такую ​​библиотеку (либо в .exe или же .dll) состоит в том, чтобы включить правильные заголовки и связать их — с Visual Studio это довольно просто.

Прежде всего, вам нужно знать 1) где размещены ваши статические библиотеки и 2) их точные имена. Перейти к свойствам проекта, а затем General, Target name содержит имя для выходного файла, в то время как Output directory указывает в какой папке ваш .lib будет размещен.

Замечания: Этот путь может быть разным для каждого проекта! Для многопроектного решения я всегда устанавливаю общий путь, чтобы избежать проблем с конфигурацией.

Теперь перейдите к свойствам проекта, который будет использовать эту библиотеку (ссылка с ней). Идти к Linker -> Input а затем добавьте имя вашего .lib в Additional dependencies (записи разделяются точкой с запятой):

Линкерный вход

Вам необходимо добавить все библиотеки, с которыми вы хотите связать. Также необходимо добавить папку, в которой эти библиотеки находятся. Linker -> General -> Additional library directories, Я упал .libs размещены в одном месте — хорошо, в противном случае скопируйте их в общую папку или добавьте несколько записей в Additional library directories список.

И последнее — помните, что вам также нужно включать заголовки с объявлениями функций и объектов, которые вы хотите использовать. Базовая вещь, я знаю, но должна быть упомянута.


ОБНОВИТЬ

неразрешенный внешний при попытке использовать библиотеку dll во внешних проектах

Ваша проблема не связанные со ссылками на всех. Дело в том, что вы неправильно поняли, связывая статическую библиотеку точно делает.

Я предполагаю, что функции сообщили как неразрешенный не используются вашими DLL, право? Но вы ожидаете, что они будут внутри, верно?

Когда ваш DLL ссылается на внешний контент (например, функцию или переменную), он разрешается во время связывания — вместе со всеми зависимостями. Но это все. Если в вашей статической библиотеке есть функция с именем print_sample_string(), но твой DLL не использует его, он не будет привязан к DLL образ. Подумайте об этом внимательно — почему это должно быть?

Еще больше — функции, которые не являются dllexportРедактирование явно не будет видно в любом случае. Функции по умолчанию имеют внешнее хранилище — так что в основном они являются частными DLLсодержание.

Таким образом, чтобы ответить на ваш вопрос напрямую — если вам нужно использовать функции / переменные из static_lib1.libприкрепите его к клиентскому приложению — так же, как вы сейчас присоединяете его к dynamic_lib, Другого пути нет. (*)


(*) По правде говоря — есть. Вы можете создать промежуточную функцию в DLL, который экспортируется и вызывает нужную функцию внутри:

Где-то в dynamic_lib:

DLL_EXP_IMP long CallFunctionFromA_Lib()
{
return some_function(); //this function is from static_lib1.lib
}

Где-то в .exe:

long result = CallFunctionFromA_Lib(); //internally this will call function from static_lib1.lib

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

12

Другие решения

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

3

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector