2016-07-14 1 views
0

Win32 응용 프로그램에서 '로드 타임 동적 링크'(모듈로드시 dll을로드하는 컴파일에서 가져 오기 라이브러리 .lib 사용)를 사용하면 검색 순서에 영향을 줄 수 있습니까?로드 타임 동적 연결과 함께 "백업"로드 경로를 지정 하시겠습니까?

정상적인 경로에서 백업 경로를 찾지 못하면 백업 경로를 사용하여 라이브러리를로드하는 것이 목표입니다.

예 : foo.lib가 프로젝트에 링크되어 있습니다.

  1. foo.dll를 시스템 경로 또는 다음로드한다 Dynamic-Link Library Search Order에 언급 된 다른 경로들 중 어느 하나에 존재하는 경우 : 부하시.

  2. 기타 mySpecifiedPath/foo.dll이로드됩니다.

설명 : 표준 LoadLibrary 검색 경로에 dll 버전이없는 경우 백업 dll을로드해야합니다.

+2

지연로드를 활성화하고 응용 프로그램 시작 중에 DLL 검색 디렉토리를 일찍 설정할 수 있습니다. – IInspectable

답변

1

하단에 이전 답을 떠나 상단에 새로 추가 : 지연 로딩과이 문제를 해결할 수있는 좋은 방법을 제공에 설명 된대로 지연로드 Failure Hook

조합을.

라이브러리에서 기호를 사용하기 전에 백업 dll을로드하는 실패 후크를 등록하십시오. 내가 무엇을 찾고 있었던 것은 지연 로딩처럼 ==============

아래

#include <Windows.h> 
#include "foo.h" 
#include <delayimp.h> 

//access to set the failure hook 
ExternC PfnDliHook __pfnDliFailureHook2; 

const char* dllName = "foo.dll"; 
const char* dllBackupPath = "pathToBackup\\foo.dll"; 
FARPROC WINAPI DelayLoadHook(unsigned dliNotify, PDelayLoadInfo pdli) 
{ 
    //if the failure was failure to load the designated dll 
    if (dliNotify == dliFailLoadLib && 
     strcmp(dllName, pdli->szDll) == 0 && 
     pdli->dwLastError == ERROR_MOD_NOT_FOUND) 
    { 
     printf("loading back-up dll\n"); 
     //return the successfully loaded back-up lib, 
     //or 0, the LoadLibrary fails here 
     HMODULE lib = LoadLibraryA(dllBackupPath); 
     return (FARPROC)lib; 
    } 
    return 0; 
} 

int main() 
{ 
    //set the Failure Hook 
    __pfnDliFailureHook2 = &DelayLoadHook; 

    //when this function is called the library will be loaded 
    //from standard paths. If it is not found the Failure Hook 
    //set above will be called. 
    int test = ::intReturningFuncFromFooDll(); 
    printf("%d", test); 
    getchar(); 
    return 0; 
} 

=========== 된 대답은 같은데 IInspectable에 의해 언급 된 바와 같이. 도움을

//load the dll using the normal search 
    HMODULE lib = LoadLibrary(L"foo.dll"); 
    //if unsuccessful, try a specified path 
    if (lib == NULL) 
    { 
    LoadLibrary(L"mySpecifiedPath/foo.dll"); 
    } 
    if (lib == NULL) 
    { 
    //make sure that the library is not used, 
    //or exit the application, as it was not found 
    } 

감사 :

Linker Support for Delay-Loaded DLLs

은 여기가 원래의 게시물에서 언급 한 사용을 보여주는 몇 가지 코드입니다 : 나는이에 관한 정보를 발견!

이전 답변으로 편집 :이 동적 로딩은 라이브러리의 모든 기호를 사용하기 전에 사용됩니다. 로드 된 지연은 라이브러리의 심볼에 처음 액세스 할 때 여기에로드 된 모듈을 사용하여 심볼 주소를 채 웁니다.

+0

이 코드는 런타임 동적 연결을 보여줍니다. 동일한 결과를 얻을 수는 있지만 많은 작업이 필요합니다. 지연로드는로드 시간에서 처음 사용까지의 가져 오기 분석을 지연 시키므로 [AddDllDirectory] (https://msdn.microsoft.com/en-us/library/windows/)를 호출하여 DLL 검색 경로를 설정할 수있는 기회를 제공합니다. desktop/hh310513.aspx)와 같이. 명시 적 LoadLinrary 및 GetProcAddress 호출이 필요 없습니다. – IInspectable

+1

'AddDllDirectory()'를 지원하지 않는 오래된 OS 버전에서는 대신'SetDllDirectory()'를 사용할 수 있습니다. 이를 지원하지 않는 구 버전의 OS에서도 [지연로드'오류 훅] (https://msdn.microsoft.com/en-us/library/sfcfb0a3.aspx)을 사용하여 백업 파일을로드 할 수 있습니다 . –

+0

@IInspectable 답변을 확장해야했습니다. GetProcAddress를 호출하지 않습니다. 첫 번째 액세스에 앞서 라이브러리를로드하고 첫 번째 호출에서 지연 로더가 프로 시저 주소를 채우도록합니다. 이를 통해 프로그램 시작시 정상 검색 경로 및 백업 dll이 없음을 감지하고 전체 실패를 일찍보고 할 수 있습니다. AddDllDirectory도 보았습니다.하지만 필자가 요구 한대로 마지막으로 검사 할 라이브러리를 보장하는 문서에서 아무것도 찾을 수 없었습니다. –

0

Dynamic-Link Library Search Order 설명서를 보면 검색된 최종 위치는 PATH 환경 변수임을 분명히해야합니다. 지식을 적용하면 모든 요구 사항을 충족하는 가장 쉬운 솔루션은 PATH 변수에 백업 위치를 추가하는 것입니다.

이 두 가지 방법으로 수행 할 수 있습니다 :

  1. 외부 실행은 다음 CreateProcess API 호출 응용 프로그램을 수는 lpEnvironment 인수를 통해 새로운 프로세스에 사용자 정의 환경을 전달합니다. 현재 프로세스의 환경 블록은 GetEnvironmentStrings을 호출하여 쿼리 할 수 ​​있습니다.

  2. /DELAYLOAD 링커 옵션을 사용하여 원하는 DLL의 지연로드를 활성화하고 응용 프로그램 시작시 프로세스 환경을 수정하십시오. PATH 환경 변수 (GetEnvironmentVariable 사용)를 검색 한 후 환경 블록에서 SetEnvironmentVariable을 호출하여 수정하고 업데이트 할 수 있습니다.

+0

'PATH'의 수정을 고려하지 않은 이유는'PATH' 디렉토리가 검색 될 순서에 관한 문서에서 어떤 보증도 찾을 수 없었기 때문입니다. 처음에 추가 된 첫 번째 것이기 때문에 사용자가 PC의 전역'PATH '에있는 것을 먼저 확인해야하지만, 정의되지 않은 동작에 의존하지 않는 것이 좋습니다. –

관련 문제