1. 程式人生 > >16 動態連結庫顯示連結與DLLMain使用示例

16 動態連結庫顯示連結與DLLMain使用示例

上一篇我們用的是動態連結庫的隱式連結,載入呼叫不需手動去設定;
動態連結庫的顯示連結使用示例:

/*
 *test.c
 */
#include <windows.h>

//1.定義函式指標
typedef int(*lpAdd)(int, int);
//2.宣告函式指標變數

lpAdd add;

int WINAPI WinMain(HINSTANCE hInstance,	
	HINSTANCE hPrevInstance,
	PSTR szCmdLine,
	int iCmdShow)
{
	//3.載入動態庫
	HINSTANCE hModule = LoadLibrary(TEXT("add.dll"));
	//4.獲取函式地址
	add = (lpAdd)GetProcAddress(hModule, "add");
	//5.呼叫函式
	int x = add(3, 5);
	//6.釋放動態連結庫
	FreeLibrary(hModule);

	return 0;
}

DLLMain使用示例:

/*
 *DllMain.c
 *此檔案用來生成DllMain.dll,生成完後放入test.c原始碼目錄下
 */
#include <windows.h>

BOOL WINAPI DllMain(
	_In_ HINSTANCE hinstDLL,
	_In_ DWORD     fdwReason,
	_In_ LPVOID    lpvReserved
	)
{
	switch (fdwReason){
		//1.DLL_PROCESS_ATTACH(LoadLibrary())
	    case  DLL_PROCESS_ATTACH:
			MessageBox(NULL, TEXT("1.DLL_PROCESS_ATTACH"), TEXT("LoadLibrary"), MB_OK);
			break;
		//2.DLL_PROCESS_DETACH(FreeLibrary())
		case  DLL_PROCESS_DETACH:
			MessageBox(NULL, TEXT("2.DLL_PROCESS_DETACH"), TEXT("FreeLibrary"), MB_OK);
			break;
		//3.DLL_THREAD_ATTACH(Thread LoadLibrary())
		case  DLL_THREAD_ATTACH:
			MessageBox(NULL, TEXT("3.DLL_THREAD_ATTACH "), TEXT("執行緒中使用LoadLibrary"), MB_OK);
			break;
		//4.DLL_THREAD_DETACH
		case  DLL_THREAD_DETACH:
			MessageBox(NULL, TEXT("4.DLL_THREAD_DETACH  "), TEXT("執行緒結束"), MB_OK);
			break;
	}
	return TRUE;
}


/*
 *test.c
 */
#include <stdio.h>
#include <windows.h>

DWORD WINAPI ThreadProc(LPVOID lpThreadParameter)
{
	HINSTANCE hModule = LoadLibrary(TEXT("DllMain.dll"));

	return 0;
}
int WINAPI WinMain(HINSTANCE hInstance,	
	HINSTANCE hPrevInstance,
	PSTR szCmdLine,
	int iCmdShow)
{
	//載入動態庫
	HINSTANCE hModule = LoadLibrary(TEXT("DllMain.dll"));
	
	CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);

	//睡一下讓建立的執行緒跑起來
	Sleep(1000);
	//釋放動態連結庫
	FreeLibrary(hModule);

	return 0;
}

由此可見,DllMain有四種情況下會被呼叫;