DLL初學者指南 非MFC

2021-04-13 04:25:17 字數 3563 閱讀 6398

我正在學習dlls,談不上對其有什麼高屋建瓴的見解;本文只是(通過)編碼讓你看到並想知道**是如何執行的。在本文中,我假定你知道如何使用你的編譯器特性,比如設定目錄路徑等等。

#ifndef _dll_tutorial_h_

#define _dll_tutorial_h_

#include #if defined dll_export

#define decldir __declspec(dllexport)

#else

#define decldir __declspec(dllimport)

#endif

extern "c"

#endif

前面兩行指示編譯器只包含這個檔案一次。extern "c"告訴編譯器該部分可以在c/c++中使用。

在vc++中這裡有兩個方法來匯出函式:

1、使用__declspec,乙個microsoft定義的關鍵字。

2、建立乙個模組定義檔案(module-definition file即.def)。第一種方法稍稍比第二種方法簡單些,但兩種都工作得很好。

__declspec(dllexport)匯出函式符號到在你的dll中的乙個儲存類。當下面一行被定義時我定義decldir來執行這個函式,

#define dll_export

同時也匯入函式如果下面一行

#define dll_export
沒有在原始檔中出現。在此情況下,你將匯出函式add(int a, int b)和function()。

現在,你需要寫乙個將要稱為dlltutorial.cpp的原始檔。

#include 

#include "dll_tutorial.h"

#define dll_export

extern "c"

decldir void function( void )

}

這裡你定義了(dll中的)所有函式。int add(int a, int b)只簡單地將兩個數相加而void function(void)只是在你的dll被呼叫時(將資訊)通知你。在我像你展示如何使用dll前,我想告訴你一些關於模組定義檔案(.def)的內容。

模組定義檔案(.def)

模組定義檔案是乙個有著.def副檔名的文字檔案。它被用於匯出乙個dll的函式,和__declspec(dllexport)很相似,但是.def檔案並不是microsoft定義的。乙個.def檔案中只有兩個必需的部分:library 和 exports。讓我們先看乙個基本的.def檔案稍後我將解析之。

library dll_tutorial

description "our ****** dll"

exports

add @1

function @2

現在你已經建立了你的dll,你需要學習如何在乙個應用程式中使用它了。當這個dll被生成後,它建立了乙個.dll檔案和乙個.lib檔案;這兩個都是你需要的。

隱式鏈結

這裡有兩個方法來載入乙個dll;乙個方法是捷徑另乙個則相比要複雜些。捷徑是只鏈結到你.lib 檔案並將.dll檔案置入你的新專案的路徑中去。因此,建立乙個新的空的win32控制台專案並新增乙個原始檔。將你做的dll放入你的新專案相同的目錄下。

#include 

#include int main()

#pragma comment(lib, "dlltutorial.lib")

請注意我讓編譯器來檢視我的dll資料夾已獲得.lib檔案同時讓它順便看下該目錄中的dll標頭檔案。如果你不想這麼做,你可以總是把他們放入你的新專案的目錄中並使用""(引號)而不是<>。這就是載入乙個dll的簡單方法。

顯示鏈結

難點的載入dll的方法是有稍微有點複雜的。你將需要函式指標和一些windows函式。但是,通過這種載入dlls的方法,你不需要dll的.lib或標頭檔案,而只需要dll。下面列出一些**,我稍後將解析之。

#include 

#include typedef int (*addfunc)(int,int);

typedef void (*functionfunc)();

int main()

_addfunc = (addfunc)getprocaddress(hinstlibrary, "add");

_functionfunc = (functionfunc)getprocaddress(hinstlibrary, "function");

if ((_addfunc == null) || (_functionfunc == null))

std::cout << _addfunc(23, 43) << std::endl;

_functionfunc();

std::cin.get();

freelibrary(hinstlibrary);

return(1);

}

首先你會注意到:這裡包括進了檔案「windows.h」同時移走了「dll_tutorial.h」。原因很簡單:因為windows.h包含了一些windows函式,當然你現在將只需要其中幾個而已。它也包含了一些將會用到的windows特定變數。你可以去掉dll的標頭檔案(dll_tutorial.h)因為-如我前面所說-當你使用這個方法載入dll時你並不需要它。

下面你會看到:以下面形式的一小塊古靈精怪的**:

typedef int (*addfunc)(int,int);

typedef void (*functionfunc)();

乙個hinstance是乙個windows資料型別:是乙個例項的控制代碼;在此情況下,這個例項將是這個dll。你可以通過使用函式loadlibrary()獲得dll的例項,它獲得乙個名稱作為引數。在呼叫loadlibrary函式後,你必需檢視一下函式返回是否成功。你可以通過檢查hinstance是否等於null(在windows.h中定義為0或windows.h包含的乙個標頭檔案)來檢視其是否成功。如果其等於null,該控制代碼將是無效的,並且你必需釋放這個庫。換句話說,你必需釋放dll獲得的記憶體。如果函式返回成功,你的hinstance就包含了指向dll的控制代碼。

一旦你獲得了指向dll的控制代碼,你現在可以從dll中重新獲得函式。為了這樣作,你必須使用函式getprocaddress(),它將dll的控制代碼(你可以使用hinstance)和函式的名稱作為引數。你可以讓函式指標獲得由getprocaddress()返回的值,同時你必需將getprocaddress()轉換為那個函式定義的函式指標。舉個例子,對於add()函式,你必需將getprocaddress()轉換為addfunc;這就是它知道引數及返回值的原因。現在,最好先確定函式指標是否等於null以及它們擁有dll的函式。這只是乙個簡單的if語句;如果其中乙個等於null,你必需如前所述釋放庫。

一旦函式指標擁有dll的函式,你現在就可以使用它們了,但是這裡有乙個需要注意的地方:你不能使用函式的實際名稱;你必需使用函式指標來呼叫它們。在那以後,所有你需要做的是釋放庫如此而已。

軟信網-程式設計-

DLL初學者指南 非MFC

譯者 小刀人 dll project.rar dll project的源 及測試專案 原文出處 codeguru 我正在學習dlls,談不上對其有什麼高屋建瓴的見解 本文只是 通過 編碼讓你看到並想知道 是如何執行的。在本文中,我假定你知道如何使用你的編譯器特性,比如設定目錄路徑等等。ifndef ...

DLL初學者指南 非MFC

dll初學者指南 非mfc 我正在學習dlls,談不上對其有什麼高屋建瓴的見解 本文只是 通過 編碼讓你看到並想知道 是如何執行的。在本文中,我假定你知道如何使用你的編譯器特性,比如設定目錄路徑等等。ifndef dll tutorial h define dll tutorial h includ...

DLL初學者指南 非MFC

notsosuperhero 譯者 小刀人 dll project.rar dll project的源 及測試 專案 原文出處 codeguru 我正在 學習dlls,談不上對其有什麼高屋建瓴的見解 本文只是 通過 編碼讓你看到並想知道 是如何執行的。在本文中,我假定你知道如何使用你的編譯器特性,比...