公告

國明的網路筆記

2016年5月29日 星期日

怎樣在C++ Builder中創建使用DLL


怎樣在  C++ Builder 中使用  DLL

使用 C++ Builder 呼叫 DLL 檔有兩個方法,將 DLL 檔透過 implib.exe 這個檔案將 DLL 檔輸出成 LIB 檔,然後將 LIB 檔加入到 C++ Builder 的專案(project)中。
將 LIB 檔加入到 C++ Builder 專案後,要再做一個 H檔。有些提供 DLL 檔的廠商會一併提供 H檔,如果沒有的話,就要自己慢慢敲囉!其他的使用方法就跟 include 其他 H 檔或是 Form 類似。
或許有人會覺得這樣轉來轉去不是很麻煩嗎?但這是我個人的習慣,習慣是一種很可怕的東西,很多東西習慣了,就不想改囉!
implib.exe 可以在 C++ Builder 的安裝路徑底下找到。
使用 implib.exe 轉檔的方法:
  implib xxx.lib xxx.dll

一、創建
   使用  File|NEW 建立一個新的  DLL 工程,並保存好檔C++ Builder 會生成一個  DLL 的程式框架。
  1DllEntryPoint 函數為一個入口方法,如果使用者在  DLL 被系統初始化或者登出時被調用,用來寫入對 DLL 的初始化程式和卸載程式;參數:hinst 用來指示  DLL 的基底位址;reason 用來指示 DLL 的調用方式,用於區別多執行緒單執行緒對  DLL 的調用、創建、卸載  DLL
  2.在程式中加入自己所要創建的  DLL 過程、函數; 
  3.用  dllimport 描述出口;
  例程式如下: 
   #include 
   #pragma hdrstop 

  extern "C" __declspec(dllexport) int test(); 

  int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason,void *) 
  {
   return 1; 
  

  int test() 
  
    return 3; 
  }

 注意:動態連結程式庫中調用過程、函數時有不同的CALL方式 __cdecl__pascal, __fastcall__stdcallBCB中預設的方式為__cdecl(可不寫),如果考慮相容性可用時__stdcall聲明方法為: 
  extern "C" __declspec(dllexport) int __stdcall test();
  對於其中過程、函數也改為: 
  int __stdcall test() 

二、使用DLL 
BCB中使用DLL有兩種方法:
  1.用靜態調用法 
  首先需要在  C++ Builder 的專案中加入輸入介面庫(import library),打開工程項目,使用BCB View|Project Manager打開專案列表,向專案中加入介面庫(*.lib) 
其次在標頭檔中加入介面聲明。 
例程式如下: 
例一:
  // define in include file 
   extern "C" __declspec(dllimport) int __cdecl test(); 
  // use function in main program 
  int I 
  I=test();

例二:
  // BCB中的宣告 *.dll
  extern "C" __declspec(dllexport) __stdcall int Myfunction_Add(int x,int y)
  {
     int z = x + y;
     return z;
  }

注意:
  (1)動態連結程式庫調用過程、函數時  CALL 方式 與創建時方式一樣不寫為__cdecl,其它需要聲明。 
  (2)C++ Builder 創建的DLL有對應的輸入介面庫(import library),如只有DLL而無庫時,可用BCBimplib工具產生:implib xxx.lib xxx.dll;另外可用:tlibxxx.lib,xxx.lst 產生DLL的內建函式列表,許多Windows的未公開技術就是用這種方法發現的。 

2.動態調用法 
 動態調用法要用Windows API 中的LoadLibrary()GetProcAddress()來調入DLL庫,指出庫中函數位置,這種方法較常見。
例程式如下: 
例一:
   HINSTANCE dd; 
   int _stdcall (*ddd)(void); 
   dd=LoadLibrary("xxx.dll");
   ddd=GetProcAddress(dd,"test"); 
   Caption=IntToStr(ddd()); 
   FreeLibrary(dd);

例二:
   int (*Myfunction_Add)(int,int);
   HINSTANCE hInst=LoadLibrary("my.dll");
   if (hInst == NULL)
   {
     ShowMessage("Null");
   }
  (FARPROC &) Myfunction_Add = GetProcAddress(hInst, "Myfunction_Add");
   int c = Myfunction_Add(10,20);
   ShowMessage(c);
   FreeLibrary(hInst);

例三:C# 引用
   //載入 + 宣告
   [DllImport("d:\\my.dll")]
   public static extern int Myfunction_Add(int x,int y);
   // 使用
   int c = Myfunction_Add(10,20);
   MessageBox.Show(c.ToString());

三、注意: 
  創建DLL時編譯連結時注意設置Project Options 
  Packages標籤:去除Builder with runtime packages檢查框。 
  Linker標籤:去除Use dynamic RTL檢查框。 
  否則創建的DLL需要Runtime packages or Runtime library

沒有留言:

張貼留言