2009-03-01 77 views
20

有没有什么办法强制Visual Studio链接所有符号从一个lib文件到dll作为atm它正在优化“未使用”的功能,这是程序使用DLL在运行时。强制视觉工作室链接在lib文件中的所有符号

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

我需要它们的原因是因为它们是全局类,它们向控制器注册它们自己,并且它们不在dll中链接。

+0

你能列出你用来编译和链接的完整命令行吗? – 2009-03-01 04:27:51

回答

19

我不知道在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; } 

这不完全是优雅的,但我们还没有找到更好的解决方案,跨平台工作。

+0

很可爱。为什么'__declspec(dllexport)'不够好? – 2010-07-23 21:02:47

+1

`__declspec(dllexport)`和`__declspec(dllimport)`是不够的,因为它们向编译器声明代码在DLL中。这使得thunk-functions和.DEF文件变得不必要。 (x) void force_link_function _ ## x(void){extern int force_link _ ## x; force_link _ ## x = 1; }` 允许将宏放置在您知道它将链接的文件的顶部。顺便说一句,虚拟函数永远不会被调用。 – 2012-04-26 16:52:09

0

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

现在如果DLL的用户要打电话给你的库函数,你的问题是有道理的。 Windows编译器(与Unix编译器不同)只有在明确请求的情况下才从DLL中导出函数。执行此操作的最常见方法是声明函数“dllexport”,但也可以将.DEF文件中的函数命名为传递给链接器。请注意,您需要在.DEF文件中列出C++错位的名称。

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) 
    
0

我使用的编译,它似乎工作,但如果不包括该行,则不会窒息。

#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标签也将它们链接。

3

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

TL; DR:

'使用库的依赖输入'

在VS lingo中'库依赖项输入'是构成库的obj文件的名称。实际上,你可以在两个作用域控制这种行为:

  1. 每refernce:由“使用库的依赖输入” 组合的参考性。这是我个人使用的 的解决方案,以及提及的in the postUse Library Dependency Inputs

  2. 每整个可执行文件:在EXE项目 性能/ C++ /连接器/一般/使用库的依赖输入 - >是

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

0

在MSVC2k17测试...

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

完全起作用。这甚至可以在一个静态链接的.lib里面,并且一直贯穿到输出可执行文件之后!

编辑:你甚至可以把它放在一个宏的奖金真棒点!

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