動態庫的創建與使用


     我們都知道庫的作用有兩個:1.文件共享的作用 2.知識產權的保護,雖然說庫的功能都是一樣的,但是動態庫的制作比靜態庫稍微麻煩一些。到底哪些地方比較麻煩呢?

1)首先創建一個Win32動態鏈接庫的工程。

2)在頭文件中給出函數的聲明,在源文件中給出函數的實現。

3)在打開工程的debug文件后我們發現有一個.dll文件,這就是傳說中的靜態庫文件。但是這個文件暫時還不能使用。我們打開這個文件發現這里面都是二進制代碼我們不能看懂。但是有專門針對二進制文件的工具。打開工具欄,點擊depends點開后將這個.dll文件拖入,我們就可以看見相應的信息,但遺憾的是我們在這里什么都沒有看見。

這就需要我們在頭文件函數聲明處加上一定的信息。將函數聲明為導出函數。如下:

當函數聲明為導出函數時,庫里面就會重新生成一個 .dll文件,還會多出一個.lib文件(如果沒有聲明為導出函數,則不會出現.lib文件)。再打開depends工具我們就會發現一個函數而不是什么都沒有。

使用方法:1)創建一個普通的文件,將動態庫里面的.dll文件和.lib文件拷貝復制到新創建普通文件的debug里面。再把相對應的頭文件也拷貝進去(動態庫的頭文件)

2)動態庫使用方式分為兩種,一種為靜態加載方式,一種為動態加載方式。

靜態加載方式:在生成動態庫的同時,也生成了靜態庫文件,這個靜態庫文件的生成是為了方便靜態加載動態庫。在程序里面引入#pragma comment(lib,"靜態庫名.lib")之后就可以使用了。但是只能使用導出了的函數。沒有生成的導出函數相當於庫中的私有成員,只能在內部使用。

      將主程序里面的.exe文件拷貝出來運行,我們發現程序不能運行,原因是不能找到相應的動態庫。但是靜態庫的.exe文件提出來后可以隨便運行,這樣我們就發現了靜態庫與動態庫的一些不同之處:靜態庫是一次編譯到處執行,他把所用到的所有庫文件信息全都包含進去,所以無論把文件放在任何地方,他的運行都不會依賴於其他文件。但動態庫不可以,他的運行必須依賴於動態庫和靜態庫。

      當程序開始運行時,整個靜態庫全部被加載到了程序里面,如果程序結束,這個庫也就自然被釋放掉,只是程序的運行必須要依賴於動態庫的文件。動態加載更靈活一些。但其加載方式就要相應的復雜一些。

動態加載方式:動態加載方式依賴於三個函數的應用。一個叫LoadLibrary()加載庫函數,一個是從加載的庫函數里獲取一個處理函數的地址的函數GetProcAddress(),另一個是釋放庫文件的函數FreeLibrary().如果我們對這些函數不熟悉的話,我們可以查看MSDN進行查看。

    要想動態加載,我們首先得加上一個頭文件:#include<windows.h>

給出一個文件句柄,使用LoadLibrary(“動態庫的名字.dll”)函數。條件判斷后,如果加載成功,相當於文件被打開了,然后在文件里獲取所需要的函數(函數必須導出過)出來。判斷獲取是否成功,如果成功就調動這個函數。處理完成后再調動庫函數FreeLibrary()釋放庫文件。

     這樣就加載完成。但是我們發現在調用GetProcAddress()函數時調用的函數名有些看不懂,這是C++文件內部對函數的命名,我們可以這樣查看:打開工具欄點擊depends,然后把動態庫文件拖進去查看他的名字。但是這種方式稍微麻煩了一點,我們可以換另外一種方式。

    在寫導出函數時給前面加上extern  "C",即聲明成C的擴展方式。擴展后即可以用普通的函數名來調用。這樣使調用變得簡便,但是必須保證函數不能重載(C語言不支持函數重載)。

    動態加載完畢,如果去掉靜態庫文件程序照常運行。它的加載只需要.dll文件即可。

  下面我們對動態庫的創建與使用做一下補充:動態鏈接庫的全局變量與類的導出。

    首先使用靜態加載的方式創建好動態庫,在頭文件里面聲明一個導出的全局變量,假如是 extern int __declspec(dllexport) g_state,然后在源文件里面定義這個變量。然后我們需要在這個動態庫的工程里面新建一個文件(名字跟動態鏈接庫的名字一樣,后綴名為.def,叫做模塊定義),添加如下代碼。

點擊加載文件,選擇所有文件,找到剛剛的.def文件,加載到工程內部。

重新編譯,將.lib文件和.dll文件重新拷貝到工程之下。這時導出的這個全局變量是一個地址,要用的時候得把他轉換成相應的函數。注意在庫里面需要把全局變量聲明為導出全局變量,在引用的時候也必須聲明成導出全局變量。

導出類的時候也是一樣的將類導出(只要導出類,類中的所有成員都會成為導出成員)。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM