2012-01-27 11 views
6

這裏是我的圖書館Lib.c文件:在命令行上創建並鏈接到Win32 DLL的確切步驟是什麼?

#include <stdio.h> 

int helloworld(){ 
    printf("Hello World DLL"); 
} 

這是我的exe Main.c文件:

int helloworld(); 


int main(int argc, char** argv){ 
    helloworld(); 
} 

我想創建Lib.dll,和Main.exe,其中Lib.dll來自對Lib.dllLib.cMain.exe聯繫。

實現此目的的具體步驟是什麼?

+1

如果你想製作一個DLL,它需要一個dllmain – 2012-01-27 16:49:50

+3

@MikeKwan:DllMain是[可選](http://msdn.microsoft.com/en-us/library/windows/desktop/ms682583%28v=vs .85%29.aspx) – tinman 2012-01-27 16:56:37

+0

在這個主題上有太多的教程,我真的不知道爲什麼麻煩問我們谷歌爲你。 – karlphillip 2012-01-27 17:04:46

回答

16

請參閱this有關如何構建DLL的相關問題。

您的庫代碼不會導出任何符號,您的可執行文件不會從庫中導入符號。下面顯示了兩種典型的模式,但您可能需要先閱讀這些模式。

第一種方法使用__declspec()在代碼中聲明哪些函數(或其他項)從DLL中導出並由其他可執行文件導入。您可以使用頭文件來聲明導出的項目,並有用於控制符號是否是出口還是進口的預處理器標誌:

mylib.h:

#ifndef MYLIB_H 
#define MYLIB_H 

#if defined(BUILDING_MYLIB) 
#define MYLIB_API __declspec(dllexport) __stdcall 
#else 
#define MYLIB_API __declspec(dllimport) __stdcall 
#endif 

#ifdef __cplusplus 
extern "C" { 
#endif 

int MYLIB_API helloworld(void); 

#ifdef __cplusplus 
} 
#endif 

#endif 

我還專門設置了調用約定__stdcall與大多數DLL函數一樣(如果我包含windows.h,我可以使用WINAPI而不是__stdcall)並聲明函數爲extern "C",這樣它們的名稱在編譯爲C++時不會變形。這裏不存在這樣的問題,因爲它全是C,但是如果您要從C源代碼構建DLL,然後嘗試從C++可執行文件使用它,那麼導入的名稱將不正確。

代碼可以再這個樣子:

mylib.c

#include "mylib.h" 
#include <stdio.h> 

int MYLIB_API helloworld(void) 
{ 
    printf("Hello World DLL"); 
    return 42; 
} 

你會使用以下命令行建立你的DLL。以及創造它會創建使用您的DLL從另一個可執行文件所需的導入庫(.LIB)的DLL(以及導出文件,但只在certain circumstances必填項):

cl /DBUILDING_MYLIB mylib.c /LD 

/DBUILDING_MYLIB參數定義用於控制DLL中的函數是導出(如果已定義)還是導入(未定義)的預處理器符號。所以你應該在構建DLL時定義它,而不是在構建應用程序時定義它。

/LD參數告訴cl產生一個DLL。

第二種方法是使用module definition files,如評論中所述。您可以使用已有的代碼,但也需要創建模塊定義文件。在它的簡單,它看起來像這樣:

LIBRARY mylib 
EXPORTS 
    helloworld 

在這種情況下,建立你需要下面的命令行的DLL:

cl /LD mylib.c /link /DEF:mylib.def 

,使其使用你的庫的頭用然後,您可以編寫應用程序你的DLL功能的進口版本:

的main.c

/* No need to include this if you went the module definition 
* route, but you will need to add the function prototype. 
*/ 
#include "mylib.h" 

int main(void) 
{ 
    helloworld(); 
    return (0); 
} 

然後,您可以使用以下命令行進行編譯(假定從DLL創建的導入庫與main.c位於同一目錄中)。這個步驟是一樣的你是否使用declspec或模塊定義文件:通過

cl main.c /link mylib.lib 

變量的/link參數傳遞後到連接器的命令行,因爲他們出現,所以只是一個文件名就被用作額外輸入鏈接到可執行文件。在這種情況下,我們指定在構建DLL時生成的導入庫。

我在這裏展示的命令行幾乎是絕對的最小需求,但它可以讓你創建一個DLL並將應用程序鏈接到它。

我認爲調用約定在所有上述內容中都是正確的,而且我還沒有試驗很多,看看在任何時候我是否都弄錯了。

+0

您應該更清楚地瞭解創建.dll的同時也會創建.lib的事實。 – 2012-01-27 17:06:31

+0

這個答案很好。如果您不喜歡使用'__declspec'擴展名,則可以創建[模塊定義文件] [http://msdn.microsoft.com/en-us/library/28d6s79h(v = vs.100).aspx]指定導出的接口。它可以更好地控制外部暴露的內容(以及如何)。 – 2012-01-27 17:21:30

+1

您可能希望使用'extern「C」'作爲導出符號,也可能使用'__stdcall'(或'WINAPI'宏)。 – 2012-01-27 17:46:52

相關問題