2012-05-02 90 views
5

按照標題,我試圖用C構建一個DLL,並將它從一個C++項目中鏈接起來。我在互聯網上閱讀並遵循不同的教程,但每次都有一些缺失,我不明白是什麼。在C中創建一個DLL,並從一個C++項目中鏈接它

下面是我做什麼,一步一步:

我創建了一個新的Win32項目,命名爲testlib,然後,從該向導,我選擇了「DLL」和「空項目」。

添加的報頭:

//testlib.h 

#include <stdio.h> 

__declspec(dllexport) void hello(); 

添加源;因爲我想這是一個C源我讀,我應該simplly重命名.C .cpp文件,所以

//testlib.c 

#include "testlib.h" 

void hello() { 
    printf("DLL hello() called\n"); 
} 

構建succeded。

現在我想在另一個項目中使用我有用的dll。

然後:新項目(testlibUse)。這次我選擇了「空項目」。
無需添加一個標題,就創建了一個CPP源

//main.cpp 
#include <testlib.h> 

int main() { 
    hello(); 
} 

然後:

  • 我添加的路徑,其中在屬性 - testlib.dll> VC++ directories->可執行文件目錄的文件夾

  • 我在屬性 - > VC++目錄 - >包含目錄中添加了testlib.h文件夾的路徑

  • 我添加的路徑testlib.lib(包括擴展名)在屬性 - >連接器 - >輸入 - >附加依賴

我試圖建立但我得到一個鏈接錯誤:

LINK : C:\path\testlibUse\Debug\testlibUse.exe not found or not built by the last incremental link; performing full link
main.obj : error LNK2019: unresolved external symbol "void __cdecl hello(void)" ([email protected]@YAXXZ) referenced in function _main
C:\path\testlibUse\Debug\testlibUse.exe : fatal error LNK1120: 1 unresolved externals

如果我回到testlib,重命名testlib.ctestlib.cpp和重建DLL,然後我能夠構建testlibUse,但我在運行時得到一個「DLL未找到」的錯誤。

我也試圖改變「釋放」這兩個項目的(改變在需要的路徑)的配置,但什麼都沒有改變。

對不起,很長的文章,但我認爲有必要正確地寫下我做了什麼。

有什麼建議嗎?

此外,如果我想在Qt項目中使用我的dll,是否需要更改任何配置參數?

回答

9

您有幾個問題:

  1. 頭文件應標記功能時被編譯在DLL導出,但進口當由圖書館用戶編譯時。
  2. 頭文件應包裝在一個extern "C"塊函數聲明時被編譯爲C++,以確保名字沒有得到錯位
  3. 的DLL是不是你的可執行文件的庫搜索路徑上,所以它不能被發現在運行時。

要解決(1)和(2),重寫首標這樣的:

#ifdef __cplusplus 
extern "C" { 
#endif 

// Assume this symbol is only defined by your DLL project, so we can either 
// export or import the symbols as appropriate 
#if COMPILING_MY_TEST_DLL 
#define TESTLIB_EXPORT __declspec(dllexport) 
#else 
#define TESTLIB_EXPORT __declspec(dllimport) 
#endif 

TESTLIB_EXPORT void hello(); 
// ... more function declarations, marked with TESTLIB_EXPORT 

#ifdef __cplusplus 
} 
#endif 

要解決(3),將DLL複製到相同的文件夾作爲可執行文件。您正在設置的「可執行文件目錄」設置不會影響DLL搜索 - 請參閱MSDN以獲取有關如何搜索DLL的詳細說明。最好的解決方案是將您的DLL複製到可執行文件所在的目錄中。您可以手動執行此操作,也可以將後期構建步驟添加到爲您執行此操作的項目中。

1

它看起來好像你需要確保編譯器不mangle在CPP構建的符號名。您應該可以將extern "C"添加到testlib中的定義中。H:

#ifdef __cplusplus 
extern "C" 
#endif 
__declspec(dllexport) void hello(); 
+0

構建成功,但我在運行時得到「dll not found」錯誤...不足以將屬性 - > VC++目錄中的路徑添加到dll - >可執行目錄中? – Saphrosit

+0

@Saphrosit:不,據我所知,這不會影響應用程序的運行。閱讀該屬性頁面上的描述;它在建立項目時影響二進制文件的發現。您需要在運行時找到DLL(例如,通過PATH環境變量)。 –

2

你應該extern "C"的包括:

+0

建立成功,但我在運行時得到一個「DLL未找到」的錯誤...是不足以將路徑添加到屬性 - > VC++目錄 - >可執行目錄的DLL? – Saphrosit

1

這是C++頭文件的一種方法,可以包含在C++中。確保只在您的DLL預處理器設置中設置TESTLIB_EXPORTS。在包含此頭文件以使用DLL的項目中,頭文件將聲明函數爲導入而不是導出。

__cplusplus guard將告訴編譯器使用C名稱修飾而不是C++名稱修飾來導入您的函數。

#include <stdio.h> 

#ifdef TESTLIB_EXPORTS 
#define TESTLIB_API __declspec(dllexport) 
#else 
#define TESTLIB_API __declspec(dllimport) 
#endif 

#ifdef __cplusplus 
extern "C" { 
#endif 

TESTLIB_API void hello(); 
/* other prototypes here */ 

#ifdef __cplusplus 
} 
#endif 
相關問題