2010-04-07 90 views
3

我想將.dll依賴項放入我的Qt項目中。將.dll導入到Qt中

所以我將此添加到我的.pro文件:

win32 { 
LIBS += C:\lib\dependency.lib 
LIBS += C:\lib\dependency.dll 
} 

然後(我不知道這是否是正確的語法或不)

#include <windows.h> 
Q_DECL_IMPORT int WINAPI DoSomething(); 

BTW該.dll外觀像這樣:

#include <windows.h> 
BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, 
             LPVOID lpReserved) 
{ 
    return TRUE; 
} 

extern "C" 
{ 
int WINAPI DoSomething() { return -1; } 
}; 

獲取錯誤:未解決的符號?

注意:我對.NET的ez pz assembly architechture之外的.dll沒有經驗,絕對是n00b。

回答

6

您的「LIBS + =」語法錯誤。試試這個:

win32 { 
    LIBS += -LC:/lib/ -ldependency 
} 

我也不能肯定,如果在你的.pro文件與驅動器盤符的絕對路徑是一個好主意 - 我通常在項目樹保持依賴的地方,並使用相對路徑。

編輯:

我想,什麼是錯在你的DLL,即不能正確導出的符號。我一直使用由QtCreator提供的模板:

  1. 裏面dll項目沒有與這樣的代碼mydll_global.h頭:

    #ifdef MYDLL_LIB 
        #define MYDLL_EXPORT Q_DECL_EXPORT 
    #else 
        #define MYDLL_EXPORT Q_DECL_IMPORT 
    #endif 
    
  2. DLL項目有定義+ = MYDLL_LIB裏面的親文件。

  3. 出口類(或僅選擇方法)和free函數都標有頭文件裏面MYDLL_EXPORT,即

    class MYDLL_EXPORT MyClass { 
    
    // ... 
    
    }; 
    
+0

我這樣做,仍然得到未定義的符號錯誤。 – 2010-04-07 06:38:22

0

你需要做函數的聲明可供鏈接器,以及提供它所在的dll的路徑。通常這是通過#include包含聲明的頭文件來完成的。

您也不需要客戶端中的Q_DECL_IMPORT宏 - 這將用於Qt庫的頭中,以允許客戶端應用程序導入該函數。根據庫或客戶端是否正在構建,類或函數將被有條件地導出/導入。更多信息可在this頁面找到。

你的依賴關係是第三方的dll還是你創建的東西?

+0

如果沒有標頭/缺少包含,則會出現編譯器錯誤,而不是鏈接器錯誤。 – chalup 2010-04-07 08:52:57

+0

你沒有說它是編譯器還是鏈接器錯誤,甚至是你正在使用的編譯器。 – 2010-04-07 17:00:47

2

如果DLL包含具有「C」鏈接的文件(即沒有C++類裝飾)並且該DLL具有頭文件和.def文件,則這是可能的。如果您沒有.def文件,您可以通過從http://www.dependencywalker.com/下載dependency walker工具輕鬆創建一個工具,以獲取導出的符號列表;您可以將此工具的輸出保存爲文本,然後提取名稱。然後創建一個名爲mylibname的文本文件。高清保存:

LIBRARY mylibname 

EXPORTS 
    FirstExportedFunctionName 
    SecondExportedFunctionName 
    ... 
    LastExpertedFunctionName 

然後運行dlltool(在MinGW的\ BIN):

dlltool -d mylibname.def -l mylibname.a 

這將產生mylibname.a,您添加到您的.pro文件:

win32:LIBS += mylibname.a 

當然,您必須提供所有文件的路徑,或將它們複製到正確的文件夾。

您還必須將頭文件修改爲第三方程序,以便您需要鏈接的DLL中的所有符號都標記爲用Q_DECL_IMPORT導入。

extern "C" { 
MYLIBAPI(retType) FirstFunctionName(arg list...); 
MYLIBAPI(retType) SecondFunctionName(arg list...); 
... 
MYLIBAPI(retType) LastFunctionName(arg list...); 
} 

其中MYLIBAPI是

#define MYLIBAPI(retType) Q_DECL_IMPORT retType 

我們使用MYLIBAPI(retType)格式,因爲這使我們能夠調整頭文件:我用 聲明所有功能.h文件爲做到這一點用於導入和創建DLL時,它還允許我們使用各種不同的編譯器和系統。

這樣做,我設法將MinGW中的QT鏈接到我使用VS 2005生成的DLL中.VS中的例程被導出爲__stdcall。您應該查看dlltool文檔,以便爲庫中的名稱添加下劃線或其他前綴。