在可执行文件中使用嵌入式.dll [英] Using an embedded .dll in an executable
问题描述
好。所以我知道有很多关于如何嵌入DLL里面的问题,但我的问题是不一样的。 (具体来说,我正在使用fmod库在我的程序中播放声音,我正在嵌入fmod.dll,但是这一点也是这样。)
我我使用Visual C ++ 2010 Ultimate。我已经成功地将.dll嵌入到.exe文件中。我的资源文件包含
#define IDR_DLL1 144
我的.rc文件包含
IDR_DLL1 DLL MOVEABLE PUREdata\\ \\\fmod.dll
我的代码中有以下功能(我完全偷了另一个stackoverflow问题):
bool extractResource(const HINSTANCE hInstance,WORD resourcesID,LPCTSTR szFilename)
{
bool bSuccess = false;
try
{
//查找并加载资源
HRSRC hResource = FindResource(hInstance,MAKEINTRESOURCE(resourceID),LDLL);
HGLOBAL hFileResource = LoadResource(hInstance,hResource);
//打开并映射到磁盘文件
LPVOID lpFile = LockResource(hFileResource);
DWORD dwSize = SizeofResource(hInstance,hResource);
//打开文件和文件映射
HANDLE hFile = CreateFile(szFilename,GENERIC_READ | GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
HANDLE hFileMap = CreateFileMapping(hFile,NULL,PAGE_READWRITE,0,dwSize,NULL);
LPVOID lpAddress = MapViewOfFile(hFileMap,FILE_MAP_WRITE,0,0,0);
//写入文件
CopyMemory(lpAddress,lpFile,dwSize);
//取消映射文件并关闭句柄
UnmapViewOfFile(lpAddress);
CloseHandle(hFileMap);
CloseHandle(hFile);
bSuccess = true;
}
catch(...)
{
//无论
}
return bSuccess;
}
然后,我在WinMain函数中调用以下代码第一件事: / p>
int WINAPI WinMain(HINSTANCE h1,HINSTANCE h2,LPSTR l,int a)
{
extractResource h1,IDR_DLL1,Lfmod.dll);
/ * etc * /
}
它可以工作。它成功地提取嵌入式fmod.dll的内容,并将其作为文件保存在同一目录中...只有... 当已经有一个fmod.dll在那里。如果fmod .dll还没有在那里,我只收到一个弹出消息说
程序无法启动,因为fmod.dll是从您的计算机中丢失。尝试重新安装程序来解决这个问题。
...换句话说,我只能覆盖已经存在的fmod.dll。例如,如果我改代我的代码到
extractResource(h1,IDR_DLL1,Lfmod2.dll);
它将写出完全相同的文件,具有完全相同的内容,名为fmod2.dll。我可以在那里摆脱原来的fmod.dll,并将新创建的fmod2.dll重命名为fmod.dll,并且它将工作。
显然,问题在于,它在寻找fmod.dll的存在之前,甚至触及我的程序的入口点。我的程序甚至不能执行任何代码,在任何fmod的东西需要实际使用之前。这似乎是非常不公平的。那么甚至可以嵌入dll的点呢?
那么,我的问题是
-
是否可以直接从.exe内部使用.dll,而不会将其解压缩为文件? (我的首选方法)
-
如果没有),那么在检查文件之前,至少可以修改我的代码来写出文件为了?
我刚刚遵循延迟加载dll的 DyP的建议。 p>
我刚在项目属性中添加了一件事,就像这样:
就是这样!
我喜欢它当编程问题有简单的解决方案。 :)
Okay. So I know there's lots of questions about how to embed dlls inside exes, but my problem is rather different. (Specifically, I'm using the fmod library to play sounds in my program, and I'm embedding the fmod.dll, but that's beside the point.)
I am using Visual C++ 2010 Ultimate. I have successfully embedded the .dll inside the .exe. My resources.h file contains
#define IDR_DLL1 144
and my .rc file contains
IDR_DLL1 DLL MOVEABLE PURE "data\\fmod.dll"
I have the following function in my code (that I totally stole from another stackoverflow question):
bool extractResource(const HINSTANCE hInstance, WORD resourceID, LPCTSTR szFilename)
{
bool bSuccess = false;
try
{
// Find and load the resource
HRSRC hResource = FindResource(hInstance, MAKEINTRESOURCE(resourceID), L"DLL");
HGLOBAL hFileResource = LoadResource(hInstance, hResource);
// Open and map this to a disk file
LPVOID lpFile = LockResource(hFileResource);
DWORD dwSize = SizeofResource(hInstance, hResource);
// Open the file and filemap
HANDLE hFile = CreateFile(szFilename, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
HANDLE hFileMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, dwSize, NULL);
LPVOID lpAddress = MapViewOfFile(hFileMap, FILE_MAP_WRITE, 0, 0, 0);
// Write the file
CopyMemory(lpAddress, lpFile, dwSize);
// Un-map the file and close the handles
UnmapViewOfFile(lpAddress);
CloseHandle(hFileMap);
CloseHandle(hFile);
bSuccess = true;
}
catch(...)
{
// Whatever
}
return bSuccess;
}
and then, I call the following code first thing in my WinMain function:
int WINAPI WinMain(HINSTANCE h1, HINSTANCE h2, LPSTR l, int a)
{
extractResource(h1, IDR_DLL1, L"fmod.dll");
/* etc */
}
It works. It successfully extracts out the contents of the embedded fmod.dll, and saves it as a file in the same directory... only... when there already was an fmod.dll there beforehand. If fmod.dll was NOT already there, I just get a popup message that says
The program can't start because fmod.dll is missing from your computer. Try reinstalling the program to fix this problem.
...In other words, I can only overwrite an fmod.dll that was already there. For example, if I instead change my code to
extractResource(h1, IDR_DLL1, L"fmod2.dll");
it will write out the exact same file, with the exact same contents, titled fmod2.dll. I can at that point get rid of the original fmod.dll, and rename the newly created fmod2.dll to fmod.dll, and it will work.
So obviously, the issue is that it looks for the presence of an fmod.dll, BEFORE even hitting the entry point of my program. My program can't even execute any code before any fmod stuff is needed to actually be used. This seems... wildly unfair. What is the point of even being able to embed dlls then?
So then, my questions are
Is it possible to use the .dll directly from inside the .exe, without unpacking it as a file? (My preferred method)
If 1.) is not possible, then how can I at least modify my code to write out the file before its presence is checked for?
Well, the solution was surprisingly easy. I just followed DyP's suggestion on delay-loading the dll.
I just added one thing in my project properties, like so:
and that was it!
I love it when programming problems have easy solutions. :)
这篇关于在可执行文件中使用嵌入式.dll的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!