다른 답변 중 일부의 제안과 달리 DllImport
속성을 사용하는 것이 여전히 올바른 접근법입니다.
나는 당신이 왜 세상의 다른 사람들처럼 할 수없고 DLL에 대한 상대 경로를 지정할 수 없는지 솔직히 이해하지 못합니다 . 예, 응용 프로그램이 설치되는 경로는 사람들의 컴퓨터마다 다르지만 기본적으로 배포시 보편적 인 규칙입니다. 이 DllImport
메커니즘은이를 염두에두고 설계되었습니다.
사실, 그것을 DllImport
다루는 것 조차도 아닙니다 . 편리한 관리 래퍼 (P / Invoke marshaller가 호출 LoadLibrary
)를 사용하는지 여부에 관계없이 사물을 관리하는 기본 Win32 DLL로드 규칙입니다 . 이러한 규칙은 여기 에 매우 자세하게 열거되어 있지만 중요한 규칙은 여기 에서 인용됩니다.
시스템은 DLL을 검색하기 전에 다음을 확인합니다.
- 동일한 모듈 이름을 가진 DLL이 메모리에 이미로드되어 있으면 시스템은로드 된 DLL을 사용하여 디렉토리에 상관없이 DLL을 사용합니다. 시스템은 DLL을 검색하지 않습니다.
- DLL이 응용 프로그램이 실행중인 Windows 버전의 알려진 DLL 목록에 있으면 시스템은 알려진 DLL (및 알려진 DLL의 종속 DLL (있는 경우))의 사본을 사용합니다. 시스템은 DLL을 검색하지 않습니다.
SafeDllSearchMode
활성화 된 경우 (기본값) 검색 순서는 다음과 같습니다.
- 애플리케이션이로드 된 디렉토리입니다.
- 시스템 디렉토리.
GetSystemDirectory
이 디렉토리의 경로를 얻으려면 함수를 사용하십시오 .
- 16 비트 시스템 디렉토리 이 디렉토리의 경로를 얻는 기능은 없지만 검색됩니다.
- Windows 디렉토리
GetWindowsDirectory
이 디렉토리의 경로를 얻으려면 함수를 사용하십시오 .
- 현재 디렉토리
PATH
환경 변수에 나열된 디렉토리 . 여기에는 App Paths 레지스트리 키로 지정된 응용 프로그램 별 경로가 포함되지 않습니다. DLL 검색 경로를 계산할 때는 앱 경로 키가 사용되지 않습니다.
따라서 DLL을 시스템 DLL과 같은 이름으로 지정하지 않는 한 (어떤 상황에서도 절대로 수행해서는 안되는) 기본 검색 순서는 응용 프로그램이로드 된 디렉토리에서 찾기 시작합니다. 설치하는 동안 DLL을 설치하면 찾을 수 있습니다. 상대 경로 만 사용하면 복잡한 문제가 모두 사라집니다.
그냥 써:
[DllImport("MyAppDll.dll")] // relative path; just give the DLL's name
static extern bool MyGreatFunction(int myFirstParam, int mySecondParam);
그러나 어떤 이유로 든 작동 하지 않고 응용 프로그램이 DLL의 다른 디렉토리를 찾도록 강제 해야하는 경우 SetDllDirectory
함수를 사용하여 기본 검색 경로를 수정할 수 있습니다 .
설명서에 따라 :
를 호출 한 후 SetDllDirectory
표준 DLL 검색 경로는 다음과 같습니다.
- 애플리케이션이로드 된 디렉토리입니다.
lpPathName
매개 변수로 지정된 디렉토리 .
- 시스템 디렉토리.
GetSystemDirectory
이 디렉토리의 경로를 얻으려면 함수를 사용하십시오 .
- 16 비트 시스템 디렉토리 이 디렉토리의 경로를 얻는 기능은 없지만 검색됩니다.
- Windows 디렉토리
GetWindowsDirectory
이 디렉토리의 경로를 얻으려면 함수를 사용하십시오 .
PATH
환경 변수에 나열된 디렉토리 .
DLL에서 가져온 함수를 처음 호출하기 전에이 함수를 호출하면 DLL을 찾는 데 사용되는 기본 검색 경로를 수정할 수 있습니다. 물론 장점 은 런타임에 계산되는이 함수에 동적 값을 전달할 수 있다는 것 입니다. DllImport
속성 으로는 가능하지 않으므로 여전히 상대 경로 (DLL의 이름 만 해당)를 사용하고 새로운 검색 순서를 사용하여 찾을 수 있습니다.
이 기능을 P / Invoke해야합니다. 선언은 다음과 같습니다.
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern bool SetDllDirectory(string lpPathName);