請參閱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並將應用程序鏈接到它。
我認爲調用約定在所有上述內容中都是正確的,而且我還沒有試驗很多,看看在任何時候我是否都弄錯了。
如果你想製作一個DLL,它需要一個dllmain – 2012-01-27 16:49:50
@MikeKwan:DllMain是[可選](http://msdn.microsoft.com/en-us/library/windows/desktop/ms682583%28v=vs .85%29.aspx) – tinman 2012-01-27 16:56:37
在這個主題上有太多的教程,我真的不知道爲什麼麻煩問我們谷歌爲你。 – karlphillip 2012-01-27 17:04:46