visual-studio 强制 Visual Studio 链接 lib 文件中的所有符号
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 
原文地址: http://stackoverflow.com/questions/599035/
Warning: these are provided under cc-by-sa 4.0 license.  You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
force visual studio to link all symbols in a lib file
提问by Lodle
Is there any way to force visual studio to link all symbols from a lib file into the dll as atm it is optimizing "unused" functions which are needed by the program using the dll at run time.
有什么方法可以强制 Visual Studio 将 lib 文件中的所有符号链接到 dll 中,因为它正在优化程序在运行时使用 dll 所需的“未使用”功能。
I tried using the /OPT:NOREF and /OPT:NOICF but they dont seem to work.
我尝试使用 /OPT:NOREF 和 /OPT:NOICF 但它们似乎不起作用。
The reason i need them is because they are global class which register them selves with a controller and they are not being linked in the dll.
我需要它们的原因是因为它们是全局类,它们将它们自己注册到控制器中,并且它们没有在 dll 中链接。
回答by Andrew Grant
I don't know if there's a more elegant way in Visual Studio, but the cross-platform solution we use it to have two macros that force the problamatic object file to be linked.
我不知道在 Visual Studio 中是否有更优雅的方式,但是我们使用它的跨平台解决方案有两个宏来强制链接问题对象文件。
One is placed in the source file of functions that are being excluded, the other is placed in a function that the linker knows will be called.
一个放置在被排除的函数的源文件中,另一个放置在链接器知道将被调用的函数中。
Something like;
就像是;
#define FORCE_LINK_THIS(x) int force_link_##x = 0;
#define FORCE_LINK_THAT(x) { extern int force_link_##x; force_link_##x = 1; }
It's not exactly elegant, but we haven't found a better solution that works across platforms.
它并不完全优雅,但我们还没有找到一个更好的跨平台解决方案。
回答by Ofek Shilon
There is actually a half-official solution to it, and here it is.
实际上有一个半官方的解决方案,这里是。
TL;DR:
特尔;博士:
'Use library dependency inputs'.
'使用库依赖项输入'。
In VS lingo 'library dependency inputs' is a name for the obj files that constitute a library. You can actually control this behaviour in two scopes:
在 VS 术语中,“库依赖项输入”是构成库的 obj 文件的名称。您实际上可以在两个范围内控制此行为:
- Per refernce: by the 'use library dependency inputs' combo in the reference properties. This is the solution I used personally, and the one mentioned in the post.  
- Per the entire executable: in the exe project properties /C++/Linker/General/ Use library dependency inputs -> Yes 
- 根据整个可执行文件:在 exe 项目属性中 /C++/Linker/General/ 使用库依赖项输入 -> 是 
The historical motivation for these arcane settings is enabling incremental linking in places it wasn't available before, but it has the useful side effect of linking directly against the obj files that are packaged in a lib, thereby constructing also unreferenced global objects.
这些神秘设置的历史动机是在以前不可用的地方启用增量链接,但它具有直接链接打包在 lib 中的 obj 文件的有用副作用,从而也构建了未引用的全局对象。
回答by Kleag
I had the same problem with a plugin system where factories in various DLLs were using a common main factory, everything registering at startup when loading libraries, without having to hard compile the list of plugins to use. This was working very well under Linux but had two problems under Windows:
我在插件系统中遇到了同样的问题,其中各种 DLL 中的工厂使用一个通用的主工厂,所有内容在加载库时在启动时注册,而无需硬编译要使用的插件列表。这在 Linux 下运行良好,但在 Windows 下有两个问题:
- factories were not common between DLLs. This is not your problem but it is related. I got a solution here: Ensuring to use common fatories. Look at the answer by James with the set_the_global function.
- they were not setup at startup if no symbol of the DLL were used in the main. I think it is your problem. The only solution I found were to use configuration files (one by subproject) listing the names of the plugins (DLLs) available and force their linking using, in my case, QLibrary. Using cmake, a default version of a configuration file for each subproject is generated at build time using the following macro, called instead of add_library in each plugin 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)
- 工厂在 DLL 之间并不常见。这不是你的问题,但它是相关的。我在这里得到了一个解决方案:确保使用通用的 fatories。使用 set_the_global 函数查看 James 的答案。
- 如果主程序中没有使用 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)
回答by Mikhail
I used a pragma, it seems to work, but doesn't choke if you don't include the line.
我使用了 pragma,它似乎有效,但如果不包含该行,则不会窒息。
#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);
    ...
}
You can also link them via the Additional Dependenciesfield in the Librariantab.
您还可以通过选项卡中的Additional Dependencies字段链接它们Librarian。
回答by Charles Lohr
Tested in MSVC2k17...
在 MSVC2k17 中测试...
__pragma(comment(linker,"/export:REGISTERfunc"));
void REGISTERfunc() { printf("I'm linked!\n" ); }
Totally works. This can even be inside a statically linked .lib and will carry through all the way to the output executable and beyond!
完全有效。这甚至可以在静态链接的 .lib 中,并且将一直执行到输出可执行文件及以后!
EDIT: You can even put it in a macro for bonus awesome points!
编辑:你甚至可以把它放在一个宏中以获得很棒的奖励积分!
EDIT: Another note: You must link-time code generation enabled. /LTCG ... something
编辑:另一个注意事项:您必须启用链接时代码生成。/LTCG ...东西
回答by MSalters
How is the DLL going to call the functions from your lib at runtime? That sounds a bit hard to believe.
DLL 将如何在运行时从您的库中调用函数?这听起来有点难以置信。
Now if users of the DLLare going to call your library functions, your question makes sense. Windows compilers (unlike Unix compilers) only export functions from a DLL if explicitly requested. The most common way to do this is to declare the function "dllexport", but you can also name the functions in a .DEF file as pass it to the linker. Note that you need to list the C++ mangled name in the .DEF file.
现在,如果DLL 的用户要调用您的库函数,那么您的问题就很有意义。Windows 编译器(与 Unix 编译器不同)仅在明确请求时才从 DLL 导出函数。执行此操作的最常见方法是声明函数“dllexport”,但您也可以将 .DEF 文件中的函数命名为将其传递给链接器。请注意,您需要在 .DEF 文件中列出 C++ 重整名称。

