Правильный способ связать статические библиотеки с dll
мой проект строит через несколько статических библиотек,которые должны быть связаны с основной библиотекой dll получить одну библиотеку в результате.
используя __declspec(dllexport)
атрибут не приводит к появлению указанных функций статических библиотек в dll, библиотек, вообще не связанных с dll.
затем я попытался построить каждую библиотеку как общую для получения собственных имен экспортированных функций и созданных .файл Def на их основе. С помощью.def файл привел к результату.
должны
__declspec(dllexport)
и.def-file
действуют одинаково в моем случае?возможно ли создать a .def файл из источников? Поскольку у меня есть код C++, я не могу писать .def-файл сам по себе из-за искажения и классов присутствия в API, подход, описанный выше с временными сгенерированными DLL, несовместим для производства.
обновление
Я хотел бы подробно объяснить о структуре моего проект. Решение состоит из нескольких проектов (модулей).
+
|
+-+ static_lib1
| +
| +--+ src
|
+-+ static_lib2
| +
| +--+ src
|
+-+ dynamic_lib (linked with static_lib1 and static_lib2)
+
+--+ src
каждый подпроект слабо зависит от других, предположим, что они не связаны для ясности. Каждый модуль имеет собственный открытый интерфейс. Я хочу иметь все модули как одну динамическую библиотеку, поэтому мой артефакт dynamic_lib.dll
, но на самом деле статические библиотеки не связаны с ним.
2 ответов
статические библиотеки не должны содержать каких-либо __declspec
или __attribute((dll...))
вещи. Они не более чем несколько объектных файлов (обычно *.obj
или *.o
), состоящего в один файл.
все, что вам нужно сделать ,чтобы использовать такую библиотеку (либо в .exe
или .dll
) должен включать правильные заголовки и связывать их - с Visual Studio это довольно легко.
прежде всего, вы должны знать 1) где ваши статические библиотеки и 2) их точные названия. Зайти в свойства проекта, а затем General
. Target name
содержит имя выходного файла, в то время как Output directory
указывает, в какой папке .lib
будет размещен.
Примечание: этот путь может отличаться для каждого проекта! Для решения с несколькими проектами я всегда устанавливаю общий путь, чтобы избежать проблем с конфигурацией.
Теперь перейдите к свойствам проекта, который будет потреблять эту библиотеку (ссылка с он.) Перейти к Linker
->Input
а затем добавить имя .lib
to Additional dependencies
(записи разделены точкой с запятой):
вам нужно добавить все библиотеки, которые вы хотите связать. Кроме того, папка, в которой размещены эти библиотеки, должна быть добавлена в Linker
->General
->Additional library directories
. Если все .lib
s помещаются в одном месте-хорошо, в противном случае скопируйте их в общее местоположение или добавьте несколько записей в Additional library directories
список.
и последний вещь-помните, что вам также нужно включить заголовки с объявлениями функций и объектов, которые вы хотите использовать. Основная вещь, я знаю, но должна быть упомянута.
обновление
неразрешенный внешний при попытке использовать библиотеку dll во внешних prodjects
ваша проблема не связанный с соединять на всех. Дело в том, что вы неправильно поняли, что, связывая статическую библиотеку именно.
я предполагаю, что функции сообщается как нерешенные не используются в вашей DLL
, да? Но вы ожидаете, что они будут внутри, верно?
когда DLL
относится к внешнему контенту (например, функции или переменной), он разрешен во время связывания - вместе со всеми зависимостями. но это все. Если ваша статическая библиотека имеет функцию с именем print_sample_string()
, но ваш DLL
не использовать это, он не будет прикреплен к DLL
изображения. Подумайте хорошенько - с чего бы это?
даже больше - функции, которые не являются dllexport
ed явно не будет виден в любом случае. Функции имеют по умолчанию внешнее хранилище - поэтому в основном они являются частными 'ы.
Итак, чтобы ответить на ваш вопрос напрямую - если вам нужно использовать функции / переменные из 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
и использовать его непосредственно.