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

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

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

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

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

  2. возможно ли создать 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 input

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

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


обновление

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

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

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

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

даже больше - функции, которые не являются dllexported явно не будет виден в любом случае. Функции имеют по умолчанию внешнее хранилище - поэтому в основном они являются частными 'ы.

Итак, чтобы ответить на ваш вопрос напрямую - если вам нужно использовать функции / переменные из 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 и использовать его непосредственно.


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