본문 바로가기
Programming/C&C++

[C++] Change dll order with SetDllDirectoryA

by tunanut 2023. 6. 15.
반응형

windows system32 폴더에 onnxruntime.dll이 포함되면서

내 프로젝트와 맞지 않는 버전이 호출되는 문제가 생겼다.

 

그래서 찾아본 결과  MSDN 에 이렇게 나와있다.

https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order

If safe DLL search mode is enabled, then the search order is as follows:
  1. DLL Redirection.
  2. API sets.
  3. SxS manifest redirection.
  4. Loaded-module list.
  5. Known DLLs.
  6. Windows 11, version 21H2 (10.0; Build 22000), and later. The package dependency graph of the process. This is the application's package plus any dependencies specified as <PackageDependency> in the <Dependencies> section of the application's package manifest. Dependencies are searched in the order they appear in the manifest.
  7. The folder from which the application loaded.
  8. The system folder. Use the GetSystemDirectory function to retrieve the path of this folder.
  9. The 16-bit system folder. There's no function that obtains the path of this folder, but it is searched.
  10. The Windows folder. Use the GetWindowsDirectory function to get the path of this folder.
  11. The current folder.
  12. The directories that are listed in the PATH environment variable. This doesn't include the per-application path specified by the App Paths registry key. The App Paths key isn't used when computing the DLL search path.
If safe DLL search mode is disabled, then the search order is the same except that the current folder moves from position 11 to position 8 in the sequence (immediately after step 7. The folder from which the application loaded).

 

 

위의 내용 중 7번에서처럼 application 과 같은 위치에 dll을 넣으면 가장 좋겠지만, 그럴 수 없는 환경이었다.

system32 폴더가 PATH environment 보다 먼저 호출되는 상황이 문제이므로, 8번 위치 위에서검색할 수 있는 방법을 찾아야했고, "SetDllDirectoryA" API를 찾았다.

 

https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-setdlldirectorya

BOOL SetDllDirectoryA(
  [in, optional] LPCSTR lpPathName
);
After calling SetDllDirectory, the standard DLL search path is:
  1. The directory from which the application loaded.
  2. The directory specified by the lpPathName parameter.
  3. The system directory. Use the GetSystemDirectory function to get the path of this directory. The name of this directory is System32.
  4. The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched. The name of this directory is System.
  5. The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
  6. The directories that are listed in the PATH environment variable.

위 내용에서 보다시피 SetDllDirectory를 사용하면 원하는 경로를 system32보다 위로(2번 위치) 검색할 수 있게 되므로,

해당 dll이 호출되기 직전 SetDllDirectory를 호출하면 원하는 dll을 호출할 수 있게 된다.

요약

  1. GetDllDirectory 로 현재 상태 백업
  2. SetDllDirectory 로 원하는 경로 등록
  3. DLL Load
  4. SetDllDirectory 로 백업해둔 경로 등록
반응형

'Programming > C&C++' 카테고리의 다른 글

[C] 입출력 함수 printf, scanf  (0) 2016.12.26