2009-03-01 37 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 ...東西