나는 런타임에서 그리고 플랫폼 비트 - 네스 (language-native)를 기반으로 자원에서 추출한 .NET 프로젝트를 가지고있다. LoadLibrary, GetProcAddress 및 FreeLibrary를 사용하여 라이브러리의로드 및 관리를 관리 코드에서 관리합니다..NET SafeHandle 클래스를 사용하고 그 안에 핸들을 결정적으로 해제 할 수 있습니까?
기본 라이브러리로 작업을 마친 후 삭제하고 싶습니다. 여기로 현재 구현 된 워크 플로우를 보여주는 몇 의사 코드의 : 유형을 IntPtr의 변수를 사용할 때 잘 작동
internal class MyClass()
{
string nativeLibraryPath = "C:\my\path\to\extracted\library.dll";
IntPtr nativeLibraryHandle = IntPtr.Zero;
public void Load()
{
nativeLibraryHandle = NativeMethods.LoadLibrary(nativeLibraryPath);
}
public void ExecuteFunction()
{
IntPtr functionPointer = NativeMethods.GetProcAddress(nativeLibraryHandle, "MyFunctionName");
// assume MyManagedDelegate is defined as the correct delegate type.
MyManagedDelegate managedFunction = Marshal.GetDelegateForFunctionPointer(functionPointer, typeof(MyManagedDelegate)) as MyManagedDelegate;
managedFunction("foo", "bar");
}
public void Unload()
{
NativeMethods.FreeLibrary(nativeLibraryHandle);
File.Delete(nativeLibraryPath);
}
}
. 현명한 지혜 (모범 사례?)는 SafeHandle이 더 나은 접근 방식 일 수 있음을 나타냅니다. 그러나, SafeHandle을 사용할 때 ReleaseHandle() 메서드는 결정적으로 호출되지 않는다는 것을 이해합니다. 즉, SafeHandle에서만 Close() 또는 Dispose() 메서드를 호출하면 은 가비지 수집 클래스로 표시됩니다. 객체가 수집 될 때까지 ReleaseHandle을 호출하지 않습니다. 네이티브 코드 .DLL이 언로드 될 때까지 삭제할 수 없기 때문에이 문제가 발생합니다. ReleaseHandle에서 FreeLibrary를 호출하면 어떻게 GC.Collect()를 호출하는 것과 같은 해커리에 의지하지 않고 라이브러리가 해제 될 때까지 결정적으로 기다릴 수 있습니까?
수정 실제 코드가 어떻게 구성되어 있는지 더 대표적으로 예를 업데이트했습니다. 이 예제에 게시 된 코드는 완전하지 않습니다. 필자는 프로덕션 코드에서 필요한 오류 검사 및 예외 처리를 포함합니다.
예에서 제공하는 의사 코드가 안전하지 않다는 것을 알고 있지만이 질문을 통해 다른 사람이 누릴 수있는 이점을 지적 해 주셔서 감사합니다. 로드 및 언로드가 클래스의 다른 메서드에 의해 처리되므로 (즉 핸들이 단일 메서드의 로컬 변수가 아니라) 제공된 예제 코드가 실제 워크 플로에 잘못된 인상을줍니다. . 그게 당신의 대답을 바꾸나요? – JimEvans
물론, 당신은 내 대답을 쓸어 버렸다. 새 버전에는 SafeHandle 또는 소멸자가 필요하며 여기서 확실히 SafeHandle을 사용하십시오. IDisposable을 구현해야합니다. –