2013-07-21 3 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이 이미하지 않은 경우, 방금 즉, 나는 단지 이미이었던 fmod.dll를 덮어 쓸 수 있습니다 ...

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

을 말한다 팝업 메시지가 표시됩니다. 예를 들어, 내가 대신이 동일한 내용, 제목 fmod2.dll으로, 동일한 파일을 작성합니다

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

에 코드를 변경합니다. 나는 그 시점에서 원래의 fmod.dll을 없애고 새로 생성 된 fmod2.dll의 이름을 fmod.dll로 바꿀 수 있습니다.  

 

그래서 분명히이 문제는 이전에도 내 프로그램의 진입 점을 치는, fmod.dll의 존재를 보이는 것입니다. 내 프로그램은 심지어 어떤 fmod 물건이 실제로 사용되기 전에 어떤 코드도 실행할 수 없다. 이건 ... 격렬하게 불공평 해 보인다. 그렇다면 dll을 임베드 할 수있는 지점은 무엇입니까?

그럼, 내 질문은

  1. 는 파일로 개봉하지 않고 .EXE 내부에서 직접 .DLL을 사용할 수 있습니까?

  2. 만약 1.)이 가능하지 않다면, 적어도 존재 여부가 확인되기 전에 파일을 작성하도록 코드를 수정할 수 있습니까?

+3

지연 로딩을 설정해야한다고 생각합니다. [this] (http://www.drdobbs.com/packing-dlls-in-your-exe/184416443?nomobile=1) (예 : 너무 오래되지 않았 으면 좋겠다.) –

+2

DLL로드 지연을위한 [MSDN 페이지] (http://msdn.microsoft.com/en-us/library/151kt790.aspx) – dyp

+0

이미 DLL을 포함하고 실행 가능하게하는 아주 좋은 방법이 있습니다. 또한 UAC 및 바이러스 스캐너에서도 작동합니다. Setup.exe, 분명히 알고 있습니다. –

답변

3

글쎄, 솔루션은 놀랍게도 쉬웠다. 방금 dll을로드 할 때 DyP's suggestion을 계속했습니다.

난 그냥과 같이, 내 프로젝트 속성에 한 가지를 추가 :

그게이었다!

프로그래밍 문제에 쉽게 해결책이 있으면이를 좋아합니다. :)

+1

그것은 내 제안이 아니지만, [n.m] (http://stackoverflow.com/users/775806/n-m).의 – dyp

+1

그것은 당신에게 해결책 일지 모르지만 그 질문에 대한 답이 아닙니다. 지연로드는 조만간 * 실제로드로 바뀝니다. 당시 Klaboom. –

+0

@HansPassant : 실제로 질문을 이해하려고 했습니까? OP는 DLL을 즉시로드합니다. 그래서, DLL이 실제로 필요합니다 (실제로드 할 때). 이미 DLL이있을 것입니다. –