維尼的蜂巢

RealTime??!! It’s amazing!!!!

動態連結函式庫(Dynamic Linking Libraries,DLLs) 六月 18, 2008

Filed under: VC++/C++/C — kevinlin @ 9:29 上午

我覺得做DLL這東西很有趣,程式執行到一半我們可以呼叫某個DLL裡面的某個function,我想寫個小範例在這邊。

DLL的載入大致上分兩種
1 、 隱式連結(Implicitly Link)(也叫載入期動態連結 Load-Time Dynamic Linking)

這種是屬於靜態載入,就是指,程式編譯時會預留函式的空間。所以當程式被Windows的loader載入到記憶體中後,loader會自動檢查執行檔中所有的import function的定義,把所有需要的DLLs都載入到記憶體裡面。
優點:
1、 使用DLL裡面的Function的方法,就像是包含在自己程式裡面的function一樣可以使用。

2 、 動作較為簡單,載入的方法跟尋找DLL的動作由作業系統負責處理,應用程式不用調整也無法去干涉。

缺點:
1 、 當找不到DLL時,程式就不能開啟(就是常見的找不到xxx.dll)。
2 、 編譯時需要先include DLL的宣告檔(通常是.h)。
3 、 隨著載入的DLLs增加,載入應用程式的速度會便慢。
4 、 若遇到不同品牌 的C++編譯器時靜態載入可就沒有這麼簡單處理了,因為當函式經過Calling Conventions的處理後,若要使用其他品牌編譯器所致造出的DLL須得大動干戈才行。

2 、 顯式連結(Explicit Linking)

跟他的名字一樣,就是在程式執行的過程中動態載入DLL,用完了就馬上釋放DLL
優點:
1 、DLL只要需要時才會載入到記憶體中,可以更有效的使用記憶體。
2 、 應用程式開始的時候不用先載入DLL,所以載入速度比上面的方法快。
3 、 編譯時不須額外include DLL函式的宣告檔。
4 、 讓我們可以更清楚DLL的載入流程。
缺點:
要多花一些程式碼來處理載入的過程!

我要介紹的是Explicit Linking

下面是test.cpp,他會產生一個test.dll

#include <iostream>
#include <Windows.h>
using namespace std;

__declspec( dllexport )  int AddFunction(int a, int b)
{ return a+b; }
__declspec( dllexport )  int SubFunction(int a, int b)
{ return a-b; }

// 進入點
BOOL APIENTRY DllMain( HANDLE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved)
{
    return TRUE;
}

接下來要教如何在程式過程中載入DLL,只有三個步驟,那就稱它為動態載入三步驟:
1.使用LoadLibrary()函式載入DLL
2.使用GetProcessAddress() 函式取得所要使用的函式的位址
3.不需要用到此DLL時,呼叫FreeLibrary()函式將DLL釋放

先把使用的程式寫出來

#include  <windows.h>
int WINAPI
WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
         LPSTR lpCmdLine, int iCmdShow){

     HINSTANCE hTest;
     HMODULE myPlugin=NULL;
     myPlugin = LoadLibrary( " test.dll " )
     //宣告function
     typedef int (*PFNAddFunction)( int a , int b);
     PFNAddFunction pfnAdd = (PFNAddFunction)GetProcAddress( myPlugin, "?AddFunction@@YAHHH@Z" );
     //宣告function
     typedef int (*PFNSubFunction)( int a , int b);
     PFNSubFunction pfnSub = (PFNSubFunction)GetProcAddress( myPlugin, "?SubFunction@@YAHHH@Z" );

     int ans;
     ans = pfnSub(5,3); //ans會是2
     ans = pfnAdd(6,4); //ans會是10

     FreeLibrary(hTest);
     return 0;
}

最有疑問的是GetProcAddress裡面的 ?AddFunction@@YAHHH@Z 是怎麼出來的??
那是我用VS2005編譯出來的函式名稱,當我們編譯成DLL後可以用VC6有附的一個工具,叫做Dependency Walker 來看編譯出來的address。

其他內容就應該是很簡單的了。

 

4 Responses to “動態連結函式庫(Dynamic Linking Libraries,DLLs)”

  1. allen501pc Says:

    請問一下,這個能夠引用到我的網誌嗎?
    最近我在找這種觀念教學,剛好你寫的文章淺顯易懂。
    可否有這個榮幸讓我把你的文章引用到我的網誌來嗎?

    我覺得你寫的很好的說 >"<

  2. […] Comment! Google找到的,引用自動態連結函式庫(Dynamic Linking Libraries,DLLs) […]

  3. […] 內容轉載自 維尼的蜂巢 […]


發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 變更 )

Twitter picture

You are commenting using your Twitter account. Log Out / 變更 )

Facebook照片

You are commenting using your Facebook account. Log Out / 變更 )

Google+ photo

You are commenting using your Google+ account. Log Out / 變更 )

連結到 %s