動態連結函式庫(簡稱DLL)

何謂動態連接函式庫:簡單來說就是一個很多函數集合的地方,可以節省執行檔空間,同時使應用程式易於升級。

前置作業:測試DLL時,必須要搭配一個執行檔,簡稱EXE(Executable)或UI(User Interface)使用。

【.DLL】函式庫:將兩數相加後回傳結果,同時必須定義一個【.H】檔,以便告知EXE如何呼叫使用原形函式。

【.EXE】執行檔:呼叫DLL內的函式Add(100,200),得到結果後顯示出來。

官方詳細說明:探訪動態連結函式庫(Dynamic Linking Libraries,DLLs)

原始程式碼:Download (解壓縮密碼:Achigo)

● 開啟新的DLL

● Achigo.cpp原始程式碼

//---------------------------------------------------------------------------
#include 		// windows.h
//---------------------------------------------------------------------------
//   Important note about DLL memory management when your DLL uses the
//   static version of the RunTime Library:
//
//   If your DLL exports any functions that pass String objects (or structs/
//   classes containing nested Strings) as parameter or function results,
//   you will need to add the library MEMMGR.LIB to both the DLL project and
//   any other projects that use the DLL.  You will also need to use MEMMGR.LIB
//   if any other projects which use the DLL will be performing new or delete
//   operations on any non-TObject-derived classes which are exported from the
//   DLL. Adding MEMMGR.LIB to your project will change the DLL and its calling
//   EXE's to use the BORLNDMM.DLL as their memory manager.  In these cases,
//   the file BORLNDMM.DLL should be deployed along with your DLL.
//
//   To avoid using BORLNDMM.DLL, pass string information using "char *" or
//   ShortString parameters.
//
//   If your DLL uses the dynamic version of the RTL, you do not need to
//   explicitly add MEMMGR.LIB as this will be done implicitly for you
//---------------------------------------------------------------------------
#include "Achigo_ExportAPI.h"

#pragma argsused
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fwdreason, LPVOID lpvReserved)
{
    return 1;
}
//---------------------------------------------------------------------------
ACHIGO_EXPORT int __stdcall Add(int a, int b)
{
   return a + b;
}
//---------------------------------------------------------------------------

● Achigo_ExportAPI.h原始程式碼

#ifndef _ACHIGO_H_
#define _ACHIGO_H_

#ifdef __cplusplus
extern "C" {
#endif

#define ACHIGO_EXPORT __declspec(dllexport)

ACHIGO_EXPORT int __stdcall Add(int a, int b);

#ifdef __cplusplus
}
#endif

#endif // End of _ACHIGO_H_

● EXE原始程式碼

//---------------------------------------------------------------------------

#include 		// vcl.h		
#pragma hdrstop

#include "U_UI.h"

#include "Achigo_ExportAPI.h"

//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    //取得DLL handle
    HINSTANCE hDLL = ::LoadLibrary("Achigo.dll");
    
    //定義函式原形
    typedef int(__stdcall *ADD)(int a, int b);

    //取得DLL function pointer
    ADD Add = (ADD)::GetProcAddress(hDLL,"Add");

    //使用函式將Edit1和Edit2相加後回傳到Edit3
    Edit3->Text = Add(StrToInt(Edit1->Text),StrToInt(Edit2->Text));

    //結束
    ::FreeLibrary(hDLL);
}
//---------------------------------------------------------------------------

::LoadLibrary()

函數說明:取得DLL的Handle。

HINSTANCE LoadLibrary(
  LPCTSTR lpLibFileName			// DLL檔案 
);

::GetProcAddress()

函數說明:取得DLL的function pointer。

BOOL CloseHandle(
  HMODULE hModule, 			// DLL的Handle
  LPCSTR lpProcName 			// 函式名稱
);

::FreeLibrary()

函數說明:釋放DLL的Handle。

BOOL GetFileTime(
  HMODULE hLibModule 			// DLL的Handle
);