2013-03-11 21 views
5

這是我第一次處理DLL。繼MSDN文檔我創建了一個頭文件fooExports.h與宏根據預處理器定義定義:如何使用__declspec(dllexport/import)將C結構從DLL /導出/導入到控制檯應用程序

#ifdef FOODLL_EXPORTS 
    #define FOO_API __declspec(dllexport) 
#else 
    #define FOO_API __declspec(dllimport) 

我的目的是無論是在我的DLL實施以及在控制檯應用程序來使用這個頭。到目前爲止,導入和導出功能工作得很好。當我嘗試導出一個已經定義的結構時,問題就出現了,我需要它作爲一個導出函數的參數。例如,在上述的頭文件我聲明FOO_API void foo(FooParams *args)args是限定的結構如下:

typedef struct FooParams 
{ 
    char *a; 
    char *b; 
    void *whatever; //some other type 
} FooParams; 

這個結構有在foo.h中進行定義,而不是在fooExports.h。有沒有什麼辦法可以導出這個結構而不需要從它的原始頭文件中取出(考慮到我想保持導出/導入集中在fooExports.h)。 這樣做會更好嗎?該DLL全部是C以及使用它的客戶端應用程序。

+0

您不導出類型,您導出鏈接器符號。 – aschepler 2013-03-11 15:20:11

+1

@aschepler你會介意擴展嗎? – wotann07 2013-03-11 15:28:03

+0

爲什麼你使用兩個.h文件或爲什麼你沒有聲明foo()的參數類型,這完全不清楚。在結構中沒有任何要導出的東西,它沒有任何代碼。避免這種困境的簡單方法是隻使用一個.h文件並完成它。 – 2013-03-11 17:25:33

回答

9

如果僅使用客戶端永遠不會有FooParams是讓指針從DLL函數返回,並將這些指針傳遞給其他DLL函數,你可以把它「不透明類型」:將

typedef struct FooParams FooParams; 

in fooExports.h。 FOO_API宏不屬於該聲明。一個不透明的類型意味着客戶端代碼不能:

  • 創建FooParams類型的任何變量(但FooParams * ptr = NULL;是好的)。
  • FooParams的任何成員都可以做任何事情。
  • 查找sizeof(FooParams) - 因此無法正確地爲malloc空間中的一個或多個FooParams對象。

對於執行上述任何操作的客戶端,您不能使用#define宏。所以,你的DLL需要有一個或多個「構造」或「工廠」的功能,可能像

FOO_API FooParams* CreateFooParams(const char * input); 

這也是很好的做法來定義匹配的「析構函數」功能類似

FOO_API void DestroyFooParams(FooParams * p); 

即使的定義與{ free(p); }一樣簡單,因爲如果DLL內部分配的內存被外部代碼釋放,反之亦然(因爲並非所有Windows代碼使用相同的mallocfree定義),有時可能會出現問題。

如果所有這些都過於極端,唯一的選擇是將struct定義放入導出的頭文件中,並使其對客戶端可見。沒有這些,除了傳遞指針外,任何試圖對FooParams執行操作的嘗試都不可能實現,因爲編譯器不會知道FooParams中的內容。編譯器(而不是鏈接器)僅從命令行參數和d文件獲取信息,而不是從庫或DLL獲取信息。

+0

非常感謝。這是一個很好的答案!在等待響應時,我直觀地將包含我的頭文件的方法與客戶端中的結構定義相結合。只是想確保沒有其他辦法。正如你剛纔解釋的那樣,我不需要做什麼。感謝你的寶貴時間! – wotann07 2013-03-11 20:01:45

相關問題