2013-07-21 39 views
1

好的。所以我知道有很多關於如何在exes中嵌入dll的問題,但是我的問題很不一樣。 (具體來說,我正在使用fmod庫在我的程序中播放聲音,並且正在嵌入fmod.dll,但那不是重點。)在可執行文件中使用嵌入式.dll

我正在使用Visual C++ 2010 Ultimate。我已成功將.dll嵌入到.exe中。我resources.h文件包含

#define IDR_DLL1 144 

和我的.rc文件包含

IDR_DLL1 DLL MOVEABLE PURE "data\\fmod.dll" 

我在我的代碼下面的函數(即我完全從另一個計算器問題偷):

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; 
} 

然後,我在我的WinMain函數中首先調用下面的代碼:

int WINAPI WinMain(HINSTANCE h1, HINSTANCE h2, LPSTR l, int a) 
{ 
    extractResource(h1, IDR_DLL1, L"fmod.dll"); 
    /* etc */ 
} 

它的工作原理。它成功地提取出嵌入式fmod.dll的內容,並將其保存爲一個文件在同一目錄中...只有... 當已經有一個fmod.dll在那裏。如果fmod.dll是不是已經在那裏,我只是得到,說

The program can't start because fmod.dll is missing from your computer. Try reinstalling the program to fix this problem. 

彈出消息......換句話說,我只能覆蓋一個fmod.dll這是已經存在。例如,如果我不是更改我的代碼以

extractResource(h1, IDR_DLL1, L"fmod2.dll"); 

就會寫出來完全相同的文件,用完全相同的內容,標題爲fmod2.dll。我可以在這一點擺脫原來的fmod.dll,並將新創建的fmod2.dll重命名爲fmod.dll,它將起作用。

   

所以,很顯然,這個問題是,它看起來對於fmod.dll的存在,甚至之前打我的程序的入口點。我的程序甚至無法在任何需要使用fmod的東西之前執行任何代碼。這似乎......非常不公平。那麼甚至能夠嵌入dll的意義何在呢?

那麼,我的問題是

  1. 是否有可能直接使用該.dll .exe文件裏面,沒有拆封的文件嗎? (我的首選方法)

  2. 如果1.)是不可能的,那麼我怎麼能至少修改我的代碼來在檢查其存在之前寫出文件?

+3

我認爲你需要設置延遲加載,參見例如[this](http://www.drdobbs.com/packing-dlls-in-your-exe/184416443?nomobile=1)(I希望它不是*太*過時)。 –

+2

[MSDN page](http://msdn.microsoft.com/zh-cn/library/151kt790.aspx)用於延遲加載DLL – dyp

+0

已經有非常好的方法來嵌入DLL並使其可執行。也適用於UAC和病毒掃描程序。 Setup.exe,當然你知道它。 –

回答

3

那麼,解決方案是驚人的容易。我只是按照延遲加載DLL的DyP's suggestion

我只是在我的項目屬性加一兩件事,像這樣:

,就是這樣!

當編程問題有簡單的解決方案時,我喜歡它。 :)

+1

這不是我的建議,但[n.m]。(http://stackoverflow.com/users/775806/n-m)。's – dyp

+1

這可能是一個解決方案,但它不是問題的答案。延遲加載遲早會變成*真實*加載。 Klaboom然後。 –

+0

@HansPassant:你真的嘗試瞭解這個問題嗎? OP會立即加載DLL。所以,到了真正需要DLL的時候(真正的加載就像你所說的那樣),它已經在那裏了。 –

相關問題