заставить Visual Studio связать все символы в файле lib - PullRequest
22 голосов
/ 01 марта 2009

Есть ли способ заставить Visual Studio связать все символы из файла lib в dll, так как atm оптимизирует «неиспользуемые» функции, которые нужны программе, использующей dll во время выполнения.

Я пытался использовать / OPT: NOREF и / OPT: NOICF, но, похоже, они не работают.

Причина, по которой они мне нужны, заключается в том, что они являются глобальным классом, который регистрирует себя с помощью контроллера, и они не связаны в DLL.

Ответы [ 6 ]

20 голосов
/ 01 марта 2009

Я не знаю, есть ли более элегантный способ в Visual Studio, но в кроссплатформенном решении мы используем его, чтобы иметь два макроса, которые принудительно связывают файл с пробламатическим объектом.

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

Что-то вроде;

#define FORCE_LINK_THIS(x) int force_link_##x = 0;

#define FORCE_LINK_THAT(x) { extern int force_link_##x; force_link_##x = 1; }

Это не совсем элегантно, но мы не нашли лучшего решения, работающего на разных платформах.

5 голосов
/ 07 сентября 2015

На самом деле есть полуофициальное решение, и здесь это .

TL; DR:

'Использовать входы зависимости библиотеки' .

В VS lingo «входы зависимости библиотеки» - это имя для obj-файлов, которые составляют библиотеку. Вы можете фактически контролировать это поведение в двух областях:

  1. По ссылке: «использовать входы зависимости библиотеки» комбо в ссылочных свойствах. Это решение, которое я использовал лично, а тот, упомянутый в посте . Use Library Dependency Inputs

  2. За весь исполняемый файл: в проекте exe properties / C ++ / Linker / General / Использовать входные данные зависимости библиотеки -> Да

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

1 голос
/ 03 сентября 2012

У меня была такая же проблема с системой плагинов, где фабрики в различных DLL-библиотеках использовали общую основную фабрику, все регистрировалось при запуске при загрузке библиотек, без необходимости составлять список плагинов для использования. Это работало очень хорошо под Linux, но было две проблемы под Windows:

  1. фабрики не были общими для DLL. Это не ваша проблема, но это связано. Я получил решение здесь: Обеспечение использования общих жиров . Посмотрите на ответ Джеймса с помощью функции set_the_global.
  2. они не были настроены при запуске, если в основном не использовался символ DLL. Я думаю, что это твоя проблема. Единственным решением, которое я нашел, было использование файлов конфигурации (по подпроектам), в которых перечислены имена доступных плагинов (DLL), и принудительно их связывание с использованием, в моем случае, QLibrary. Используя cmake, версия конфигурации по умолчанию для каждого подпроекта генерируется во время сборки с использованием следующего макроса, который вызывается вместо add_library в каждом плагине dir:

    file(WRITE ${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}-plugins "")
    macro (DECLARE_AMOSE_PLUGIN _plugin)
      file (APPEND ${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}-plugins "${_plugin}\n")
      add_library(${_plugin} SHARED ${${_plugin}_LIB_SRCS})
    endmacro (DECLARE_AMOSE_PLUGIN)
    
0 голосов
/ 17 марта 2017

Проверено в MSVC2k17 ...

__pragma(comment(linker,"/export:REGISTERfunc"));
void REGISTERfunc() { printf("I'm linked!\n" ); }

Полностью работает. Это может даже быть внутри статически связанного .lib и будет проходить через весь выходной исполняемый файл и далее!

РЕДАКТИРОВАТЬ: Вы даже можете поместить его в макрос для получения бонусных очков!

РЕДАКТИРОВАТЬ: Другое примечание: Вы должны включить генерацию кода времени соединения. / LTCG ... что-то

0 голосов
/ 21 июля 2015

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

#include "library1.h"
#include <QApplication>
#pragma comment(lib, "C:\\Qt\\5.5\\msvc2013_64\\lib\\Qt5Guid.lib")
PHI_STATUS PHI_EXP_CONV PHI_ShowGUI(size_t reserved)
{
    QApplication app(none, nullptr);
    ...
}

Вы также можете связать их через поле Additional Dependencies на вкладке Librarian.

0 голосов
/ 02 марта 2009

Как DLL будет вызывать функции из вашей библиотеки во время выполнения? В это трудно поверить.

Теперь, если пользователи DLL будут вызывать функции вашей библиотеки, ваш вопрос имеет смысл. Компиляторы Windows (в отличие от компиляторов Unix) экспортируют функции только из DLL, если это явно требуется. Самый распространенный способ сделать это - объявить функцию "dllexport", но вы также можете назвать функции в файле .DEF, передав их компоновщику. Обратите внимание, что вам нужно указать искаженное имя C ++ в файле .DEF.

...