1. 建立步骤
VS新建工程/添加项目 -> Win32 -> Win32项目 -> 下一步 -> 应用程序类型:DLL -> 完成
2. 文件代码
dllmain.cpp: DllMain入口函数(详细)
#include "stdafx.h"
void ShowDebug(LPTSTR lpstrFormat, ...);
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
ShowDebug(TEXT("process attach\n")); // 静态链接和动态链接的LoadLibrary时
break;
case DLL_THREAD_ATTACH:
ShowDebug(TEXT("thread attach\n")); // 线程中加载
break;
case DLL_THREAD_DETACH:
ShowDebug(TEXT("thread detach\n")); // 线程中卸载
break;
case DLL_PROCESS_DETACH:
ShowDebug(TEXT("process detach\n")); // 静态链接结束,动态链接FreeLibrary,程序退出
break;
}
return TRUE;
}
符号导出:
(1) .def
添加->新建项->模块定义文件
DEF文件的写法:
LIBRARY MyDll // 库名为MyDll,省略库名即为动态链接库文件名
EXPORTS // 输出
Insert @1 // 带序号的输出函数名
Delete @2
Member @3
Min @4
CallWndProcHook.def:
LIBRARY MyDll
EXPORTS
fnCallWndProcHook @1
使用LoadLibrary/FreeLibrary(如果涉及到导出类,变量则需要用第二种方式):
int main(int argc, char **argv)
{
typedef int (*pFn)(void);
HINSTANCE hinst = LoadLibrary(TEXT("CallWndProcHook.dll"));
pFn fn = (pFn)GetProcAddress(hinst, "fnCallWndProcHook");
//cout << "fnCallWndProc: " << fnCallWndProcHook() << endl;
cout << "fnCallWndProc: " << fn() << endl;
FreeLibrary(hinst);
system("pause");
return 0;
}
运行结果:
(2) 导出符号
新建工程时勾选”导出符号“:
将生成CallWndProcHook.h文件,如:
#ifdef CALLWNDPROCHOOK_EXPORTS // 在CallWndProcHook.cpp中为1,dllexport输出符号
#define CALLWNDPROCHOOK_API __declspec(dllexport)
#else
#define CALLWNDPROCHOOK_API __declspec(dllimport)
#endif
// 此类是从 CallWndProcHook.dll 导出的
class CALLWNDPROCHOOK_API CCallWndProcHook {
public:
CCallWndProcHook(int nDll);
int GetMember() const;
private:
int m_nMyDll;
};
extern CALLWNDPROCHOOK_API int nCallWndProcHook;
CALLWNDPROCHOOK_API int fnCallWndProcHook(void);
CallWndProcHook.cpp:
// CallWndProcHook.cpp : 定义 DLL 应用程序的导出函数。
//
#include "stdafx.h"
#include <tchar.h>
#include <string>
#include "CallWndProcHook.h"
// 这是导出变量的一个示例
CALLWNDPROCHOOK_API int nCallWndProcHook=0;
// 这是导出函数的一个示例。
CALLWNDPROCHOOK_API int fnCallWndProcHook(void)
{
return 42;
}
// 这是已导出类的构造函数。
// 有关类定义的信息,请参阅 CallWndProcHook.h
CCallWndProcHook::CCallWndProcHook(int nDll) : m_nMyDll(nDll)
{
return;
}
int CCallWndProcHook::GetMember() const
{
return m_nMyDll;
}
void ShowDebug(LPTSTR lpstrFormat, ...)
{
va_list VAList;
va_start(VAList, lpstrFormat);
TCHAR szBuf[MAX_PATH * 2] = {0};
_vstprintf_s(szBuf, MAX_PATH, lpstrFormat, VAList);
OutputDebugString(szBuf);
}
主程序中:
#include "../CallWndProcHook/CallWndProcHook.h" // 符号声明, 在使用的程序中为dllimport
#pragma comment(lib, "../Debug/CallWndProcHook.lib") // lib中存放符号的入口位置
void DllWinThread(LPVOID lP)
{
cout << "Thread call: " << fnCallWndProcHook() << endl;
}
int main(int argc, char **argv)
{
cout << "fnCallWndProc: " << fnCallWndProcHook() << endl;
CCallWndProcHook cwp(16);
cout << "dllClass: " << cwp.GetMember() << endl;
HANDLE hThread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE)DllWinThread, // 线程函数
NULL, // 函数参数
0, NULL);
WaitForSingleObject(hThread, INFINITE); // 无限期等待线程执行结束
CloseHandle(hThread);
system("pause");
return 0;
}
运行结果: