合并DLL2011-01-13任明汉前言你可能不希望在发布程序时附带上一个外部的 DLL,因为可能会有些用户在无意中把 DLL 删除了而造成 EXE 不能正确运行,也有可能该 DLL 会被别人拿去使用,也有可能,此 DLL 会成为破解者破解你的程序的突破口。无论出于何种原因,如果你想把一个 DLL 合并到一个 EXE 中的话,本文向你介绍这种方法。Win32 程序调用 DLL 的机制Win32 EXE 在调用一个外部 DLL 中的函数时,首先要调用 LoadLibary 函数来载入此 DLL 到程序的进程地址空间。如果 LoadLibary 载入此 DLL 成功,将返回一个该 DLL 的句柄。这个句柄实际上就是该 DLL 在内存中的起始地址。在载入 DLL 成功后,还必须调用 GetProcAddress 函数来获取要调用的函数的地址。然后再根据该地址来调用这个函数。根据上述原理,我们可以把一个 DLL 作为资源文件放到 EXE 文件中,在程序运行时,分配一块内存,然后将此资源复制到该分配的内存中,并根据该内存地址计算得到相关的导出函数地址,然后,当我们需要调用某一函数时,可以用该函数在内存中的地址来调用它。程序实现。首先,把要合并的 DLL 作为资源加入到项目的资源文件中,然后在程序运行时,从资源中载入该资源,以得到该 DLL 在内存中的位置:LPVOID sRawDll; // 资源文件在内存中的地址
HRSRC hRes;
HMODULE hLibrary;
HGLOBAL hResourceLoaded;
char lib_name[MAX_PATH];
GetModuleFileName(hInstance, lib_name, MAX_PATH ); // 得到运行程序的名字
hLibrary = LoadLibrary(lib_name); // 就象载入一个 DLL 一样载入运行程序到内存中
if (NULL != hLibrary)
{
// 得到指定的资源文件在内存中的位置
hRes = FindResource(hLibrary, MAKEINTRESOURCE(IDR_DATA1), RT_RCDATA);
if (NULL != hRes)
{
// 将资源文件载入内存
hResourceLoaded = LoadResource(hLibrary, hRes);
if (NULL != hResourceLoaded)
{
// 得到资源文件大小
SizeofResource(hLibrary, hRes);
// 锁定资源以得到它在内存中的地址
sRawDll = (LPVOID)LockResource(hResourceLoaded);
}
}
else return 1;
FreeLibrary(hLibrary);
}
else return 1;