Подтвердить что ты не робот

Force visual studio для соединения всех символов в файле lib

Есть ли способ заставить визуальную студию связывать все символы из файла lib в dll как atm, он оптимизирует "неиспользуемые" функции, которые необходимы программе, используя DLL во время выполнения.

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

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

4b9b3361

Ответ 1

Я не знаю, есть ли более элегантный способ в 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; }

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

Ответ 2

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

TL; ДР:

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

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

  • В реферере: с помощью "входных зависимостей библиотеки библиотеки" комбо в ссылочных свойствах. Это решение, которое я использовал лично, и упомянутый в сообщении. Использовать вкладки зависимостей библиотеки

  • За весь исполняемый файл: в проекте exe свойства/С++/Linker/Общие/Использовать входные данные библиотеки → Да

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

Ответ 3

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

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

    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)
    

Ответ 4

Как DLL собирается вызывать функции из вашей библиотеки во время выполнения? Это немного сложно поверить.

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

Ответ 5

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

#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.

Ответ 6

Протестировано в MSVC2k17...

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

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

EDIT: вы можете даже поместить его в макрос для бонусных потрясающих очков!

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