動(dòng)態(tài)鏈接庫(kù)

          動(dòng)態(tài)連接庫(kù)(Dynamic link library),是一些編譯過(guò)的可以執(zhí)行的代碼模塊,后綴為.dll
          1 DLL的基本理論
          ? 在使用普通函數(shù)庫(kù)時(shí),可以在程序連接時(shí)將庫(kù)中的代碼拷貝到執(zhí)行文件中,這時(shí)靜態(tài)鏈接,在多個(gè)同樣程序執(zhí)行時(shí),體統(tǒng)保留了許多
          代碼副本,造成了內(nèi)存資源的浪費(fèi)。在使用dll時(shí),不必將dll鏈接到程序中,而是在應(yīng)用程序運(yùn)行時(shí)動(dòng)態(tài)的裝載dll,裝載dll被映射
          到進(jìn)程的地址空間中。同時(shí),使用dll 并不時(shí)將庫(kù)代碼拷貝,只是在程序中記錄了函數(shù)的入口點(diǎn)和接口。
          2 DLL 的優(yōu)點(diǎn)
          ?1) 節(jié)省系統(tǒng)資源
          ?2) 不僅可以包括可執(zhí)行代碼,還可以包括數(shù)據(jù)和各種資源
          ?3)支持多語(yǔ)言
          ?4)升級(jí)可以僅僅覆蓋dll 文件
          ?5)dll 獨(dú)立編程語(yǔ)言,c++builder 中的dll vc 也可以使用
          3導(dǎo)入導(dǎo)出匹配
          ??? DLL函數(shù)一般有兩種函數(shù),內(nèi)部函數(shù)(internal)和導(dǎo)出函數(shù)(export).在實(shí)際情況下,許多DLL 調(diào)用了其他DLL里面的函數(shù),因此
          DLL可以同時(shí)有導(dǎo)入和導(dǎo)出函數(shù)。
          ???? DLL 包含有一個(gè)導(dǎo)出函數(shù)表,可以通過(guò)函數(shù)的符號(hào)化的名字和稱為序號(hào)的正書來(lái)識(shí)別這些函數(shù),函數(shù)表中包含了函數(shù)在dll內(nèi)部的
          地址。在動(dòng)態(tài)鏈接進(jìn)程好建立一張表,把客戶的調(diào)用與dll里的函數(shù)的地址連接起來(lái)。
          ??? double dbValue(value);//內(nèi)部函數(shù)
          ??? double dbValue(value);//內(nèi)部函數(shù)
          ??? extern"c" _declspec(dllexpoert) double changeValue(double,bool);//外部函數(shù)
          ?? double dblValue(double value)
          ?? {
          ?????? return value*vlaue;
          ?? }
          ?? double changeValue(double value,bool whichOp)
          ? {
          ???? return whichOp?doublValue(value):halfValue(value);
          ?? }
          ? 如果我們希望dll可以用于其他語(yǔ)言或不同版本的c++ 需要在聲明導(dǎo)出函數(shù)的時(shí)候加上extern "C."
          ?4 隱式的鏈接和顯示的鏈接
          ?? 隱式鏈接(前面所講)在創(chuàng)建dll 的時(shí)候,鏈接器產(chǎn)生一個(gè)lib 文件把拿獲了dll中的導(dǎo)出符號(hào)和序號(hào)
          ?? 顯示鏈接調(diào)用Win32 的LoadLibrary 函數(shù),使用完后,調(diào)用 FreeLibrary.
          ?5 查找dll
          ?? 依次順序?yàn)榘琫xe 的目錄,進(jìn)程的當(dāng)前目錄,Windows 目錄,path 環(huán)境變量里列出的目錄。
          ?6 創(chuàng)建動(dòng)態(tài)鏈接庫(kù)
          ?? (如何查看dll 文件的定義)
          ?7 導(dǎo)出函數(shù):extern "C" __declspec(dllexport) ExportType FunctionName(Parameter)
          ??? extern "C" __declspec(dllimport) __stdcall void CreateFromFunct();
          ??? extern "C" __declspec(dllexport) __stdcall void CreateFromFunct();//導(dǎo)出函數(shù)
          ??? 導(dǎo)出類:class __declspec(dllexport) ExportType ClassName{...}
          ??? class __declspec(dllexport) __stdcall MyDllClass { //導(dǎo)出類
          ???? public:
          ??? MyDllClass();
          ??? void CreateAForm();
          ??? TDllFrm* DllMyForm;
          ??? };

          ???? __declspec(dllimport) class __stdcall MyDllClass {
          ?????? public:
          ?????? MyDllClass();
          ?????? void CreateAForm();
          ?????? TDllFrm* DllMyForm;
          ??? };
          ??? 靜態(tài)調(diào)用,build 生成dll 文件和lib 文件,并把lib 文件導(dǎo)入到工程中
          ???? void __fastcall TForm1::Button1Click(TObject *Sender)
          ??? { // 導(dǎo)出類實(shí)現(xiàn),導(dǎo)出類只能使用靜態(tài)方式調(diào)用
          ?????? DllClass = new MyDllClass();
          ?????? DllClass->CreateAForm();??
          ??? }
          ??? void __fastcall TForm1::Button2Click(TObject *Sender)
          ??? { // 導(dǎo)出函數(shù)實(shí)現(xiàn)
          ?????? CreateFromFunct();
          ???? }
          ???? void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
          ??? {
          ???????? delete DllClass;
          ???? }
          ?? 動(dòng)態(tài)調(diào)用
          ?? class TForm1 : public TForm
          ? {
          ???????? ...
          ????? private: // User declarations
          ????? void (__stdcall *CreateFromFunct)();
          ?????????? ...
          ?? }
          ? HINSTANCE DLLInst = NULL;
          ? void __fastcall TForm1::Button2Click(TObject *Sender)
          ? {??
          ???? if( NULL == DLLInst ) DLLInst = LoadLibrary("DLL.dll"); //上面的 Dll
          ???? if (DLLInst) {
          ???????????? CreateFromFunct = (void (__stdcall*)()) GetProcAddress(DLLInst,
          ????????????????????????? "CreateFromFunct");
          ????? if (CreateFromFunct) CreateFromFunct();
          ????? else ShowMessage("Could not obtain function pointer");
          ?? }
          ????? else ShowMessage("Could not load DLL.dll");
          ? }
          ?? void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
          ? {
          ???? if ( DLLInst ) FreeLibrary (DLLInst);
          ? }
          8? bcb 調(diào)用vc 編寫的DLL
          ? 1) 名字分解
          ?? 1. 名字分解:
          ? 沒(méi)有名字分解的函數(shù)
          ??? TestFunction1 // __cdecl calling convention
          ??? @TestFunction2 // __fastcall calling convention
          ??? TESTFUNCTION3 // __pascal calling convention
          ??? TestFunction4 // __stdcall calling convention
          ? 有名字分解的函數(shù)
          ??? @TestFunction1$QV // __cdecl calling convention
          ??? @TestFunction2$qv // __fastcall calling convention
          ??? TESTFUNCTION3$qqrv // __apscal calling convention
          ??? @TestFunction4$qqrv // __stdcall calling convention
          ? 使用 extern "C" 不會(huì)分解函數(shù)名
          ?? 2)
          ????? __cdecl 缺省
          ?? 是 Borland C++ 的缺省的 C 格式命名約定,它在標(biāo)識(shí)符前加一下劃線,以保留
          ? 它原來(lái)所有的全程標(biāo)識(shí)符。參數(shù)按最右邊參數(shù)優(yōu)先的原則傳遞給棧,然后清棧。
          ??? extaern "C" bool __cdecl TestFunction();
          ?? 在 def 文件中顯示為
          ??? TestFunction @1
          ?? 注釋: @1 表示函數(shù)的順序數(shù),將在“使用別名”時(shí)使用。

          ? __pascal Pascal格式
          ?? 這時(shí)函數(shù)名全部變成大寫,第一個(gè)參數(shù)先壓棧,然后清棧。
          ??? TESTFUNCTION @1 //def file

          ? __stdcall 標(biāo)準(zhǔn)調(diào)用
          ?? 最后一個(gè)參數(shù)先壓棧,然后清棧。
          ??? TestFunction @1 //def file

          ? __fastcall 把參數(shù)傳遞給寄存器
          ?? 第一個(gè)參數(shù)先壓棧,然后清棧。
          ??? @TestFunction @1 //def file
          ? 3)
          ?? 3. 解決調(diào)用約定:
          ?? Microsoft 與 Borland 的 __stdcall 之間的區(qū)別是命名方式。 Borland 采用
          ? __stdcall 的方式去掉了名字起前的下劃線。 Microsoft 則是在前加上下劃線,在
          ? 后加上 @ ,再后跟為棧保留的字節(jié)數(shù)。字節(jié)數(shù)取決于參數(shù)在棧所占的空間。每一個(gè)
          ? 參數(shù)都舍入為 4 的倍數(shù)加起來(lái)。這種 Miocrosoft 的 DLL 與系統(tǒng)的 DLL 不一樣。
          ?4 查看dll 的調(diào)用接口tdump -ee MyDll.dll >1.txt (查看 1.txt 文件即可)
          5 編輯c++ builder build 為一個(gè)可以直接調(diào)用的 .exe 。 點(diǎn)擊project option? 中l(wèi)inker 標(biāo)簽 去掉user dynamic RTL 選項(xiàng) 和package 中 去掉builder with runtime package 選項(xiàng).
          6 調(diào)用代參數(shù)的vl 編寫的dll 調(diào)用的實(shí)例。
          int (__cdecl *fun)(char*,char*,char*);

          HINSTANCE DLLInst = NULL;
          void __fastcall TForm1::Button1Click(TObject *Sender)
          {
          if( NULL == DLLInst )
          {
          DLLInst = LoadLibrary("HollyIVRCard.dll");
          }
          if(DLLInst)
          {
          ? fun=(int (__cdecl*)(char*,char*,char*))GetProcAddress(DLLInst,"hTrade");
          ? if(fun)
          ? {
          ??? cardid=Edit1->Text.c_str();
          ??? num=Edit2->Text.c_str();
          ??? ShowMessage(fun(cardid,num,res));
          ??? //cout<<cardid<<endl;
          ??? //cout<<num<<endl;
          ? }
          } else{
          ?? ShowMessage("load dll fail");
          }
          ?? ShowMessage(AnsiString(res));
          }

          posted on 2006-09-06 18:13 康文 閱讀(390) 評(píng)論(0)  編輯  收藏 所屬分類: c\c++

          <2006年9月>
          272829303112
          3456789
          10111213141516
          17181920212223
          24252627282930
          1234567

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(1)

          隨筆分類

          隨筆檔案

          文章檔案

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 怀柔区| 汪清县| 当阳市| 扎囊县| 隆昌县| 浦江县| 思茅市| 西青区| 梁山县| 东安县| 蓝田县| 库尔勒市| 来宾市| 丰宁| 临夏市| 开阳县| 贵阳市| 开平市| 宁化县| 祁门县| 六安市| 务川| 广元市| 建平县| 五家渠市| 蒙山县| 西峡县| 延津县| 静安区| 尉犁县| 吉林省| 蓬溪县| 临西县| 瓦房店市| 瓮安县| 温泉县| 柞水县| 托克托县| 东山县| 开化县| 清丰县|