動態鏈接庫編程

動態鏈接庫編程


一。引入:
    爲了使多個程序員協作開發程序,負責底層功能的程序員使用動態鏈接庫實現具體功能,負責用戶界面設計的程序員在項目中引用動態鏈接庫,並調用其中的具體功能,這樣就可以使程序具有很好的模塊化結構,便於定位和調試問題。

 

二。擴展名解釋:
        dll – Dynamic-link library – 動態鏈接庫
1. dll –- 共享庫
2.ocx –- 包含Active控件的動態鏈接庫
3.drv --- 系統驅動程序

 

三。相關知識概括(如下圖):


四。代碼示例

// dllmain.cpp : 定義 DLL 應用程序的入口點。
//生成項目,可以得到一個.dll文件和一個.lib文件.

#include <windows.h>

// DLLMain是DLL的入口函數
BOOL APIENTRY DllMain( HMODULE hModule,				// DLL的句柄			
                       DWORD  ul_reason_for_call,	// 指定調用DLL入口函數的原因
                       LPVOID lpReserved			// 指定DLL初始化和清理的方式
					 )
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH: // DLL正在加載到當前進程時虛擬地址空間
	case DLL_THREAD_ATTACH:	// 進程正在創建一個線程,並在線程中加載DLL
	case DLL_THREAD_DETACH:	// 表示調用DLL的線程正在清理和退出
	case DLL_PROCESS_DETACH:// 表示在進程退出過程中或調用FreeLibrary()函數時,DLL正在從當前進程的虛擬地址空間卸載
		break;
	}
	return TRUE;
}

// 添加導出函數
extern "C"_declspec(dllexport) int sum (int a, int b)
{
	return a + b;
}

// 添加導出類
class _declspec(dllexport) CMath
{
public:
	CMath(void);
	int sum(int , int);
	~CMath(void);
};

CMath::CMath(void)
{
}

int CMath::sum(int a, int b)
{
	return a + b;
}

CMath::~CMath(void)
{
}


 

// HideReferenceDLL.cpp -- 隱式鏈接使用DLL

#include <iostream>
#include <Windows.h>

// 隱式鏈接:加載動態鏈接庫
#pragma comment(lib, "win32.lib")

// 導出聲明不能在函數裏面使用,鏈接時應該在函數的外部使用(全局作用域)
extern "C" int sum(int a, int b);
extern "C" class _declspec(dllexport)CMath
{
public:
	CMath(void);
	int sum(int , int);
	~CMath(void);
};

int main()
{
	std::cout << "5 + 6 = "	<< sum(5, 6) << std::endl
		<< "成功引用DLL中的導出函數\n";

	CMath testClass;
	std::cout << "7 + 8 = "	<< testClass.sum(7, 8)	<< std::endl
		<< "成功引用DLL中的導出類\n";

	system("pause");
	return 0;
}


 

// obviousReferenceDLL.cpp -- 顯式鏈接

#include <stdio.h>
#include <Windows.h>

int main()
{
// 申請變量
	HINSTANCE hinstLib;	// 指定DLL模塊的句柄
	typedef int (*PROCSUM)(int, int);
	PROCSUM procSum;    // 指定DLL模塊中導出模塊的地址

// 加載DLL文件,獲取DLL句柄
	hinstLib = LoadLibrary(TEXT("win32.dll"));

// 如果句柄有效,則獲取函數sum()的地址
	if(NULL != hinstLib){
		wprintf(L"LoadLibrary() is OK!\n");
		procSum = (PROCSUM) GetProcAddress(hinstLib, "sum"); // 獲取dll導出函數的地址
		// If the function address is valid, call the functuon.
		if(procSum != NULL){
			printf("GetProcAddress() is OK!\n");
			printf("5+6 = %d\n", (procSum)(5, 6));
		}
		else{
			printf("LoadLibrary() failed, error %d\n", GetLastError());
			FreeLibrary(hinstLib);
		}
	}
	else{
		printf("LoadLibrary() failed, error %d \n", GetLastError());
	}

	system("pause");
	return 0;
}


 

 

五。學習參考資料
1.  MSDN Library for Visual Studio 2005
2. 《Windows系統編程》 李曉黎 編著
3. 《Windows系統編程》 Johnson M.Hart 著

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章