第一次用 C++ 寫 DLL 就上手

DLL 簡介

動態連結函式庫(英語:Dynamic-link library,縮寫為DLL)是微軟公司在微軟視窗作業系統中實作共享函式庫概念的一種實作方式。這些函式庫函式的副檔名是.DLL、.OCX(包含ActiveX控制的函式庫)或者.DRV(舊式的系統驅動程式)。

所謂動態連結,就是把一些經常會共用的程式碼(靜態連結的OBJ程式庫)製作成DLL檔,當執行檔呼叫到DLL檔內的函式時,Windows作業系統才會把DLL檔載入記憶體內,DLL檔本身的結構就是可執行檔,當程式需求函式才進行連結。透過動態連結方式,記憶體浪費的情形將可大幅降低。靜態連結函式庫則是直接連結到執行檔。

DLL的文件格式與視窗EXE文件一樣——也就是說,等同於32位元視窗的可移植執行文件(PE)和16位元視窗的New Executable(NE)。作為EXE格式,DLL可以包括原始碼、資料和資源的多種組合。

在更廣泛的意義上說,任何同樣文件格式的電腦檔案都可以稱作資源DLL。這樣的DLL的例子有副檔名為ICL的圖示函式庫、副檔名為FON和FOT的字型文件。

DLL 的撰寫

本文件是用 Visual Studio 2012 來做 DLL 開發示範

首先開新專案 TestDLL2012

開新專案1

開新專案2

選擇應用程式類型 DLL

選擇DLL

然後 Visual Studio 會產生 TestDLL2012.h 跟 TestDLL2012.cpp

TestDLL2012.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 下列 ifdef 區塊是建立巨集以協助從 DLL 匯出的標準方式。
// 這個 DLL 中的所有檔案都是使用命令列中所定義 TESTDLL2012_EXPORTS 符號編譯的。
// 在命令列定義的符號。任何專案都不應定義這個符號
// 這樣一來,原始程式檔中包含這檔案的任何其他專案
// 會將 TESTDLL2012_API 函式視為從 DLL 匯入的,而這個 DLL 則會將這些符號視為
// 匯出的。
#ifdef TESTDLL2012_EXPORTS
#define TESTDLL2012_API __declspec(dllexport)
#else
#define TESTDLL2012_API __declspec(dllimport)
#endif

// 這個類別是從 TestDLL2012.dll 匯出的
class TESTDLL2012_API CTestDLL2012 {
public:
CTestDLL2012(void);
// TODO: 在此加入您的方法。
};

extern TESTDLL2012_API int nTestDLL2012;

TESTDLL2012_API int fnTestDLL2012(void);

TestDLL2012.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// TestDLL2012.cpp : 定義 DLL 應用程式的匯出函式。
//

#include "stdafx.h"
#include "TestDLL2012.h"


// 這是匯出變數的範例
TESTDLL2012_API int nTestDLL2012=0;

// 這是匯出函式的範例。
TESTDLL2012_API int fnTestDLL2012(void)
{
return 42;
}

// 這是已匯出的類別建構函式。
// 請參閱 TestDLL2012.h 中的類別定義
CTestDLL2012::CTestDLL2012()
{
return;
}

接下來就按照 Visual Studio 的範例來寫函式吧~

首先在標頭檔加入

1
TESTDLL2012_API int __stdcall fnTestDll(int a,int b);

然後在實作檔加入

1
2
3
TESTDLL2012_API int __stdcall add(int a,int b){
return a+b;
}

為什麼加入 __stdcall 可以參考這篇

之後加入 .def 檔案

加入.def檔案

在裡面加入

1
2
3
4
LIBRARY	"TestDLL2012"

EXPORTS
add @1

之後在專案->屬性->連結器->輸入->模型定義檔

輸入 TestDLL2012.def

建置專案就行了

VB.Net呼叫DLL

將建置好的 .dll 檔跟複製到預設執行檔底下的資料夾

然後宣告 DLL 函式

1
Public Declare Auto Function add Lib "TestDLL2012.dll" (ByVal a As Integer, ByVal b As Integer) As Integer

就可以在VB裡面呼叫這個函式囉>.^

C++呼叫DLL

將建置好的 .dll 檔跟 .lib 複製到跟 main.cpp 底下的資料夾

在 main.cpp 加入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>

#include "TestDLL2012.h"

using namespace std;

int main(){

int a = 3, b = 5;

int c = add(a,b);

cout<<"a + b = "<<c<<endl;

return 0;

}

然後到專案->屬性->連結器->輸入->其他相依性

加入 TestDLL2012.lib

建置之後就可以執行了

參考

  1. 動態連結函式庫