Utilisation d’un fichier .dll incorporé dans un exécutable

D’accord. Donc, je sais qu’il y a beaucoup de questions sur la façon d’intégrer les dll dans les exes, mais mon problème est assez différent. (Plus précisément, j’utilise la bibliothèque fmod pour reproduire les sons dans mon programme et j’intègre le fichier fmod.dll, mais ce n’est pas la question.)

J’utilise Visual C ++ 2010 Ultimate. J’ai intégré avec succès le fichier .dll dans le fichier .exe. Mon fichier resources.h contient

#define IDR_DLL1 144 

et mon fichier .rc contient

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

J’ai la fonction suivante dans mon code (que j’ai totalement volé d’une autre question de stackoverflow):

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

et ensuite, j’appelle le code suivant en premier dans ma fonction WinMain:

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

Ça marche. Il extrait avec succès le contenu du fichier fmod.dll incorporé et l’enregistre en tant que fichier dans le même répertoire … uniquement … lorsqu’il existait déjà un fichier fmod.dll. Si fmod.dll n’était PAS déjà là, je reçois juste un message contextuel indiquant

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

… En d’autres termes, je ne peux écraser qu’un fichier fmod.dll déjà présent. Par exemple, si je change plutôt mon code en

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

il écrira exactement le même fichier, avec exactement le même contenu, intitulé fmod2.dll. À ce stade, je peux me débarrasser du fichier fmod.dll d’origine et renommer le fichier fmod2.dll récemment créé en fmod.dll. Cela fonctionnera.

Alors, évidemment, le problème est qu’il recherche la présence d’un fichier fmod.dll, AVANT même de bash le point d’entrée de mon programme. Mon programme ne peut même pas exécuter de code avant que tout élément fmod ne soit réellement utilisé. Cela semble … extrêmement injuste. Quel est le sharepoint même être en mesure d’intégrer des dll alors?

Alors, mes questions sont

  1. Est-il possible d’utiliser le fichier .dll directement à l’intérieur du fichier .exe, sans le décompresser sous forme de fichier? (Ma méthode préférée)

  2. Si 1.) n’est pas possible, comment puis-je au moins modifier mon code pour écrire le fichier avant que sa présence ne soit vérifiée?

Eh bien, la solution était étonnamment facile. Je viens de suivre la suggestion de DyP sur le chargement différé de la DLL.

Je viens d’append une chose dans les propriétés de mon projet, comme ceci:

et c’était ça!

J’adore quand les problèmes de programmation ont des solutions faciles. 🙂