Мой проект строится через несколько статических библиотек, которые должны быть связаны с основной библиотекой DLL, в результате получают одну DLL.
С помощью __declspec(dllexport)
Атрибут не приводит к появлению указанных функций статических библиотек в dll, библиотеки вообще не связаны с dll.
Затем я попытался собрать каждую библиотеку как общую для получения собственных имен экспортируемых функций и создал на их основе файл .def. Использование файла .def приводит к результату.
Должен __declspec(dllexport)
а также .def-file
действовать одинаково в моем случае?
Можно ли создать файл .def из источников? Поскольку у меня есть код на C ++, я не могу самостоятельно написать файл .def из-за искажения и классов присутствия в API, описанный выше подход с использованием временных сгенерированных dll несовместим с производством.
Я хотел бы подробно объяснить структуру моего проекта. Решение состоит из нескольких проектов (модулей).
+
|
+-+ static_lib1
| +
| +--+ src
|
+-+ static_lib2
| +
| +--+ src
|
+-+ dynamic_lib (linked with static_lib1 and static_lib2)
+
+--+ src
Каждый подпроект слабо зависит от других, давайте предположим, что они не связаны для ясности. Каждый модуль имеет собственный открытый интерфейс. Я хочу, чтобы все модули были единой динамической библиотекой, поэтому мой артефакт dynamic_lib.dll
, но на самом деле статические библиотеки не связаны с ним.
Статические библиотеки не должны содержать никаких __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
, Я упал .lib
s размещены в одном месте — хорошо, в противном случае скопируйте их в общую папку или добавьте несколько записей в 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
и использовать его напрямую.