日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++ dll的隐式与显式调用

發(fā)布時間:2023/12/10 c/c++ 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++ dll的隐式与显式调用 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.


轉(zhuǎn)載自:http://blog.sina.com.cn/s/blog_53004b4901009h3b.html


  應(yīng)用程序使用DLL可以采用兩種方式:一種是隱式鏈接,另一種是顯式鏈接。在使用DLL之前首先要知道DLL中函數(shù)的結(jié)構(gòu)信息。Visual C++6.0(或者更先進(jìn)的版本)在VC\bin目錄下提供了一個名為Dumpbin.exe的小程序(使用方法見VS自帶工具:dumpbin的使用),用它可以查看DLL文件中的函數(shù)結(jié)構(gòu)。另外,Windows系統(tǒng)將遵循下面的搜索順序來定位DLL: 1.包含EXE文件的目錄,2.進(jìn)程的當(dāng)前工作目錄, 3.Windows系統(tǒng)目錄, 4.Windows目錄,5.列在Path環(huán)境變量中的一系列目錄。

  1.隱式鏈接

  隱式鏈接就是在程序開始執(zhí)行時就將DLL文件加載到應(yīng)用程序當(dāng)中。實現(xiàn)隱式鏈接很容易,只要將導(dǎo)入函數(shù)關(guān)鍵字_declspec(dllimport)函數(shù)名等寫到應(yīng)用程序相應(yīng)的頭文件中就可以了。下面的例子通過隱式鏈接調(diào)用MyDll.dll庫中的Min函數(shù)。首先生成一個項目為TestDll,在DllTest.h、DllTest.cpp文件中分別輸入如下代碼:

//Dlltest.h#include"MyDll.h" #pragma comment(lib,"MyDll.lib") extern "C"_declspec(dllimport) int Max(int a,int b); extern "C"_declspec(dllimport) int Min(int a,int b); //TestDll.cpp #include"Dlltest.h" void main() {int a; a=min(8,10) printf("比較的結(jié)果為%d\n",a); }


  在創(chuàng)建DllTest.exe文件之前,要先將MyDll.dll和MyDll.lib拷貝到當(dāng)前工程所在的目錄下面,也可以拷貝到windows的System目錄下。如果DLL使用的是def文件,要刪除TestDll.h文件中關(guān)鍵字extern "C"。TestDll.h文件中的關(guān)鍵字Progam commit是要Visual C+的編譯器在link時,鏈接到MyDll.lib文件,當(dāng)然,開發(fā)人員也可以不使用#pragma comment(lib,"MyDll.lib")語句,而直接在工程的Setting->Link頁的Object/Moduls欄填入MyDll.lib既可。

  2.顯式鏈接

  顯式鏈接是應(yīng)用程序在執(zhí)行過程中隨時可以加載DLL文件,也可以隨時卸載DLL文件,這是隱式鏈接所無法作到的,所以顯式鏈接具有更好的靈活性,對于解釋性語言更為合適。不過實現(xiàn)顯式鏈接要麻煩一些。在應(yīng)用程序中用LoadLibrary或MFC提供的AfxLoadLibrary顯式的將自己所做的動態(tài)鏈接庫調(diào)進(jìn)來,動態(tài)鏈接庫的文件名即是上述兩個函數(shù)的參數(shù),此后再用GetProcAddress()獲取想要引入的函數(shù)。自此,你就可以象使用如同在應(yīng)用程序自定義的函數(shù)一樣來調(diào)用此引入函數(shù)了。在應(yīng)用程序退出之前,應(yīng)該用FreeLibrary或MFC提供的AfxFreeLibrary釋放動態(tài)鏈接庫。下面是通過顯式鏈接調(diào)用DLL中的Max函數(shù)的例子。

#include <windows.h> #include <cstdio> void main(void) { typedef int(*pMax)(int a,int b); typedef int(*pMin)(int a,int b); HINSTANCE hDLL; PMax Max HDLL=LoadLibrary("MyDll.dll");//加載動態(tài)鏈接庫MyDll.dll文件; Max=(pMax)GetProcAddress(hDLL,"Max"); A=Max(5,8); Printf("比較的結(jié)果為%d\n",a); FreeLibrary(hDLL);//卸載MyDll.dll文件; }

  在上例中使用類型定義關(guān)鍵字typedef,定義指向和DLL中相同的函數(shù)原型指針,然后通過LoadLibray()將DLL加載到當(dāng)前的應(yīng)用程序中并返回當(dāng)前DLL文件的句柄,然后通過GetProcAddress()函數(shù)獲取導(dǎo)入到應(yīng)用程序中的函數(shù)指針,函數(shù)調(diào)用完畢后,使用FreeLibrary()卸載DLL文件。在編譯程序之前,首先要將DLL文件拷貝到工程所在的目錄或Windows系統(tǒng)目錄下。

  使用顯式鏈接應(yīng)用程序編譯時不需要使用相應(yīng)的Lib文件。另外,使用GetProcAddress()函數(shù)時,可以利用MAKEINTRESOURCE()函數(shù)直接使用DLL中函數(shù)出現(xiàn)的順序號,如將GetProcAddress(hDLL,"Min")改為GetProcAddress(hDLL, MAKEINTRESOURCE(2))(函數(shù)Min()在DLL中的順序號是2),這樣調(diào)用DLL中的函數(shù)速度很快,但是要記住函數(shù)的使用序號,否則會發(fā)生錯誤。

注意兩點:

1.上面中提到extern "C",表明函數(shù)使用c語言的風(fēng)格編譯函數(shù),這樣后面顯式調(diào)用時,GetProcAddress第二個參數(shù)就是原來的函數(shù)名,否則如果使用C++編譯的話支持函數(shù)重載,則第二個參數(shù)會發(fā)生變化,想要知道發(fā)生了什么變化,可以使用前面提到的Dumpbin工具查看dll的生成函數(shù)。具體參考文章:http://www.cnblogs.com/laogao/archive/2012/12/07/2806528.html

2.MAKEINTRESOURCE()函數(shù)可以代替復(fù)制dll生成的函數(shù)的一大串字符串名,但是必須知道函數(shù)生成的順序,所以你也必須打開dll查看,才能知道。


總結(jié)

以上是生活随笔為你收集整理的C++ dll的隐式与显式调用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。