C++ 创建引用DLL
親手嘗試了一下創建并引用DLL一種方式,記錄一下過程。
使用的語言為C++,IDE使用的為VS2010
說一下我自己的理解。程序編譯是指編譯當前程序中寫的代碼,當然應用程序中有可能還會包含著已經其他的開發人員開發的代碼,這時不需要編譯他們的代碼,因為有可能他們就沒給你源代碼,這個時候要把他們提供的代碼鏈接到應用程序中,怎么用呢。一般來說是會提供一個lib文件,或dll文件。簡單說一下認識。
有兩種方式把這些lib文件或者dll文件引進過來,一種是靜態鏈接,一種是動態鏈接。
靜態鏈接是把這些lib和dll直接加入到應用程序生成的exe文件中,這樣的話會導致exe比較大,占用比較大的存儲空間。lib文件中直接就是把obj文件直接壓進lib文件中,在使用的過程中把lib和.h加入到工程中,直接編譯就可以了。
而開發靜態庫時, 你只需要在頭文件聲明函數或者類,然后再實現文件里實現函數或類就可以了。
使用的時候,.h頭文件加到工程里,然后再指定要鏈接的.lib文件,就可以了。
可用#pragma comment(lib, "libfilepath")來指定要鏈接的靜態庫。或者在project->dependency里設置。
libfilepath可以設定為相對路徑使用.\ ?..\等來指定路徑。
動態鏈接使用dll文件,這個文件實際上里面都是函數的描述和定義,其實和exe文件很相似,但是它不能單獨的執行。這個文件不能單獨使用,一般要和lib文件一起配合使用,這個lib文件就和靜態的不是一個意思,這個lib文件里面不是包括obj文件,而是對dll中的函數的位置,參數等的描述,作用類似于h文件,對dll中函數進行說明。這個dll文件不會加入到exe文件中,所以在程序執行的時候必須有exe和dll文件共同存在。這種動態鏈接的好處是
1、擴展了應用程序的特性;
2、可以用許多種編程語言來編寫;
3、簡化了軟件項目的管理;
4、有助于節省內存;
5、有助于資源共享;
6、有助于應用程序的本地化;
7、有助于解決平臺差異;
靜態鏈接庫和動態庫(DLL)的另外一個區別在于靜態鏈接庫中不能再包含其他的動態鏈接庫或者靜態庫,而在動態鏈接庫中還可以再包含其他的動態或靜態鏈接庫。
本文主要是針對于動態鏈接進行介紹
先說一下創建DLL
1.先創建工程,導出符號要勾選上
2.代碼如下
3.編譯后生成的了dll和lib文件
動態鏈接的使用方式又分為兩種,一種稱為靜態的,一種稱為動態的。
開發和使用dll需注意三種文件:
1)dll頭文件
它是指dll中說明輸出的類或符號原型或數據結構的.h文件。當其它應用程序調用dll時,需要將該文件包含入應用程序的源文件中。
2)dll的引入庫文件(.lib)
它是dll在編譯、鏈接成功后生成的文件。主要作用是當其它應用程序調用dll時,需要將該文件引入應用程序。否則,dll無法引入。
3)dll文件(.dll)
它是應用程序調用dll運行時,真正的可執行文件。dll應用在編譯、鏈接成功后,.dll文件即存在。開發成功后的應用程序在發布時,只需要有.exe文件和.dll文件,不必有.lib文件和dll頭文件。
從使用的角度上來看,如何靜態調用,則要用到lib文件,而動態調用則不用,只需要DLL文件就夠了。
DLL的調用分為動態和靜態兩種:動態調用和靜態調用。動態調用方式的特點是完全由編程者用 API 函數加載和卸載 DLL,程序員可以決定 DLL 文件何時加載或不加載,顯式鏈接在運行時決定加載哪個 DLL 文件。
動態調用,即顯式調用方式,是由編程者用API函數加載和卸載DLL來達到調用DLL的目的,比較復雜,但能更加有效地使用內存,是編制大型應用程序時的重要方式。在Windows系統中,與動態庫調用有關的函數包括:
①LoadLibrary(或MFC 的AfxLoadLibrary),裝載動態庫。
②GetProcAddress,獲取要引入的函數,將符號名或標識號轉換為DLL內部地址。
③FreeLibrary(或MFC的AfxFreeLibrary),釋放動態鏈接庫。
靜態調用,也稱為隱式調用,由編譯系統完成對DLL的加載和應用程序結束時DLL卸載的編碼(Windows系統負責對DLL調用次數的計數),調用方式簡單,能夠滿足通常的要求。通常采用的調用方式是把產生動態連接庫時產生的.LIB文件加入到應用程序的工程中,想使用DLL中的函數時,只須在源文件中聲明一下。
LIB文件包含了每一個DLL導出函數的符號名和可選擇的標識號以及DLL文件名,不含有實際的代碼。Lib文件包含的信息進入到生成的應用程序中,被調用的DLL文件會在應用程序加載時同時加載在到內存中。
靜態調用方式的特點是由編譯系統完成對DLL的加載和應用程序結束時 DLL 的卸載。當調用某DLL的應用程序結束時,若系統中還有其它程序使用該 DLL,則Windows對DLL的應用記錄減1,直到所有使用該DLL的程序都結束時才釋放它。靜態調用方式簡單實用,但不如動態調用方式靈活。
靜態加載過程
1.先建一個工程
2.現在要設置工程了,這個環節很重要。
先把MyDLL.dll中的聲明文件MyDLL.h加入到T_MyDLL工程中,如果這里不這么設置的話,則要MyDLL.h引入到工程中。實際上這個文件只是在編譯中用到,最終的exe不需要這個文件,所以這里建議通過在工程中設定一下。在工程上點右鍵,屬性,進行設置,在“附加包含目錄”中把路徑設成剛剛MyDLL的目錄,注意路徑要到MyDLL.h這個路徑下。
這里介紹這里設置的“附加包含目錄”。
這里簡單說一下和上面的“VC++目錄”的區別
“VC++ Directories -> Include Directories” : Directory settings displayed in the window are the directories that Visual Studio will search for include files referred to in your source code files. Corresponds to environment variable INCLUDE. More information : http://msdn.microsoft.com/en-us/library/t9az1d21(v=vs.80).aspx
“C/C++ -> General -> Additional Include Directories”: The directory to be added to the list of directories searched for include files. More information : http://msdn.microsoft.com/en-us/library/73f9s62w(v=vs.80).aspx
下面那個鏈接講的比較清楚了:
The compiler searches for directories in the following order:
1.Directories containing the source file.
2.Directories specified with the /I option, in the order that CL encounters them.
3.Directories specified in the INCLUDE environment variable.
order2中的/I是由C/C++ -> General -> Additional Include Directories設置的。
order3中的INCLUDE是由VC++ Directories -> Include Directories設置的。
設置完了MyDLL.h的路徑后還要設置依賴文件MyDLL.lib的路徑,因為MyDLL.lib是對DLL文件的說明,所以沒有設置這個文件的路徑的話,在程序鏈接的時候會找不到對應的MyDLL.dll中定義的函數。
這時不用設置MyDLL.dll文件,你也可以把這個dll文件拷到和T_MyDLLDlg.cpp文件同一個路徑下。
設計的界面如下。
代碼如下
效果就是實現一個簡單的加法動作。
編譯完生成一個exe文件
這時候把.exe文件和.dll文件拷到一個文件夾里,就可以執行了。如果不放.dll文件的話單執行exe的話是不能執行的。
動態鏈接的例子,用到上面的3個函數就可以了,這里不過多介紹。
動態調用要知道DLL的文件路徑,并且知道接口函數的類型及參數,并不需要依賴到.h文件、lib文件等內容。
但是,要動態調用DLL里面的函數的話,那么在該函數的前面必須要添加一個extern "C"(聲明為C編譯、連接方式的外部函數),不然動態調用會找不到這個函數地址的。
如下,在MyDLL.h中添加下列代碼:
extern "C" MYDLL_API int Add(int a, int b);
在MyDLL.cpp中添加下列代碼:
MYDLL_API int Add(int a, int b)
{
return a + b;
}
創建一個MFC對話框應用程序,然后在初始化函數中加入下列代碼:
{
CDialog::OnInitDialog();
// ....省略其他代碼
//加載MyDLL.dll
HINSTANCE hDllInst = AfxLoadLibrary(_T("MyDLL.dll"));
//判斷是否加載成功
if(hDllInst)
{
? ? //根據DLL里面的封裝函數來定義函數指定
typedef int(*pAdd)(int ,int);
pAdd myAdd;
? ? ? ? //根據函數名來從已加載的DLL中獲取函數地址并賦值
myAdd = (pAdd)GetProcAddress(hDllInst, "Add");
? ? ? ? //判斷是否獲取成功
if(myAdd != NULL)
{
? ? ? ? ? ? ?//調用該函數
int a = myAdd(10, 20);
CString str;
str.Format(_T("%d"), a);
TRACE(str);
}
? ? ? ? //釋放加載的DLL
AfxFreeLibrary(hDllInst);
}
return TRUE;
}
轉載于:https://blog.51cto.com/mingsuper/1350943
總結
以上是生活随笔為你收集整理的C++ 创建引用DLL的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android使用 LruCache 缓
- 下一篇: 自定义消息编码绑定实现