動態(tài)鏈接庫

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

          ???? __declspec(dllimport) class __stdcall MyDllClass {
          ?????? public:
          ?????? MyDllClass();
          ?????? void CreateAForm();
          ?????? TDllFrm* DllMyForm;
          ??? };
          ??? 靜態(tài)調用,build 生成dll 文件和lib 文件,并把lib 文件導入到工程中
          ???? void __fastcall TForm1::Button1Click(TObject *Sender)
          ??? { // 導出類實現(xiàn),導出類只能使用靜態(tài)方式調用
          ?????? DllClass = new MyDllClass();
          ?????? DllClass->CreateAForm();??
          ??? }
          ??? void __fastcall TForm1::Button2Click(TObject *Sender)
          ??? { // 導出函數(shù)實現(xiàn)
          ?????? CreateFromFunct();
          ???? }
          ???? void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
          ??? {
          ???????? delete DllClass;
          ???? }
          ?? 動態(tài)調用
          ?? 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 調用vc 編寫的DLL
          ? 1) 名字分解
          ?? 1. 名字分解:
          ? 沒有名字分解的函數(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" 不會分解函數(shù)名
          ?? 2)
          ????? __cdecl 缺省
          ?? 是 Borland C++ 的缺省的 C 格式命名約定,它在標識符前加一下劃線,以保留
          ? 它原來所有的全程標識符。參數(shù)按最右邊參數(shù)優(yōu)先的原則傳遞給棧,然后清棧。
          ??? extaern "C" bool __cdecl TestFunction();
          ?? 在 def 文件中顯示為
          ??? TestFunction @1
          ?? 注釋: @1 表示函數(shù)的順序數(shù),將在“使用別名”時使用。

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

          ? __stdcall 標準調用
          ?? 最后一個參數(shù)先壓棧,然后清棧。
          ??? TestFunction @1 //def file

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

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

          導航

          統(tǒng)計

          常用鏈接

          留言簿(1)

          隨筆分類

          隨筆檔案

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 夏河县| 运城市| 巍山| 兴隆县| 徐闻县| 额尔古纳市| 大方县| 即墨市| 兴安县| 澄江县| 阜康市| 无极县| 策勒县| 伊宁市| 台江县| 广饶县| 林口县| 青铜峡市| 策勒县| 沧州市| 万山特区| 孝感市| 油尖旺区| 丹巴县| 多伦县| 河池市| 扎兰屯市| 黄大仙区| 胶南市| 稻城县| 民和| 饶河县| 山东省| 通海县| 玛多县| 盐城市| 金湖县| 包头市| 绥棱县| 阿城市| 四平市|