强制visual studio链接lib文件中的所有符号

时间:2009-03-01 01:09:14

标签: c++ visual-studio linker

有没有办法强制visual studio将lib文件中的所有符号链接到dll中,因为它正在优化程序在运行时使用dll所需的“未使用”函数。

我尝试使用/ OPT:NOREF和/ OPT:NOICF,但它们似乎不起作用。

我需要它们的原因是因为它们是全局类,它们用控制器注册它们并且它们没有在dll中链接。

6 个答案:

答案 0 :(得分:20)

我不知道Visual Studio中是否有更优雅的方式,但我们使用跨平台解决方案有两个宏来强制将problamatic目标文件链接起来。

一个放在被排除的函数的源文件中,另一个放在链接器知道将被调用的函数中。

喜欢的东西;

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

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

它不是很优雅,但我们还没有找到适用于跨平台的更好的解决方案。

答案 1 :(得分:5)

实际上有一个半官方的解决方案,here it is

TL; DR:

'使用库依赖项输入'

在VS lingo'库中,依赖项输入'是构成库的obj文件的名称。您实际上可以在两个范围中控制此行为:

  1. Per refernce:'使用库依赖输入' 参考属性中的组合。这是我使用的解决方案 个人而言,提及in the postUse Library Dependency Inputs

  2. 根据整个可执行文件:在exe项目中 properties / C ++ / Linker / General /使用库依赖项输入 - >是

  3. 这些神秘设置的历史动机是enabling incremental linking in places it wasn't available before,但它具有直接链接到lib中打包的obj文件的有用副作用,从而构建未引用的全局对象。

答案 2 :(得分:1)

我在插件系统中遇到了同样的问题,其中各种DLL中的工厂使用了一个公共的主工厂,一切都在启动时在加载库时注册,而不必硬编译要使用的插件列表。这在Linux下运行良好,但在Windows下有两个问题:

  1. 工厂在DLL之间并不常见。这不是你的问题,但它是相关的。我在这里得到了一个解决方案:Ensuring to use common fatories。看看James使用set_the_global函数的答案。
  2. 如果主要没有使用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)
    

答案 3 :(得分:0)

我使用了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);
    ...
}

您还可以通过Additional Dependencies标签中的Librarian字段链接它们。

答案 4 :(得分:0)

在MSVC2k17中测试......

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

完全有效。这甚至可以在静态链接的.lib中,并且将一直传递到输出可执行文件以及更远的地方!

编辑:你甚至可以把它放在宏观中,以获得额外的奖励!

编辑:另一个注意事项:您必须启用链接时代码生成。 / LTCG ......某事

答案 5 :(得分:-1)

DLL如何在运行时从lib调用函数?这听起来有点难以置信。

现在,如果 DLL的用户要调用您的库函数,那么您的问题是有道理的。 Windows编译器(与Unix编译器不同)仅在明确请求时从DLL导出函数。最常见的方法是声明函数“dllexport”,但您也可以将.DEF文件中的函数命名为传递给链接器。请注意,您需要在.DEF文件中列出C ++受损名称。