2010-07-13 2 views
3

먼저 dllimport 속성과 getProcAddress 함수를 직접 비교하는 것이 적절하지 않다는 것을 알고 있습니다. 오히려, 나는 dllimport 속성을 가진 함수를 가져 오거나 getProcAddress 함수를 사용하여 dll에서 함수를 호출하는 것과 기본적으로 같은 것을 달성하는 코드 두 개를 비교하는 데 관심이 있습니다. 특히, 필자가 작성한 DLL에서 일부 기능을 사용하는 C# 응용 프로그램을 작성하고 있습니다. 처음에 나는 다음과 같은 코드 조각으로 내 DLL 함수에 액세스 :dllimport와 getProcAddress의 차이점

class DllAccess 
{ 
    [DllImport("kernel32.dll", SetLastError = true)] 
    private extern IntPtr LoadLibrary(String DllName); 

    [UnmanagedFunctionPointer(CallingConvention.StdCall)] 
    private delegate Bool BarType(Byte arg); // return value indicates whether function call went well or not. 

    Bool Bar(Byte arg) 
    { 
     Bool ok = false; 
     IntPtr pDll= LoadLibrary("foo.dll"); 
     if (pDll != IntPtr.Zero) 
     { 
      IntPtr pfunc = GetProcAddress(pDll, "bar"); 
      if (pFunc != IntPtr.Zero) 
      { 
       BarType bar = (BarType)Marshal.GetDelegateForFunctionPointer(pFunc, typeof(BarType)); 
       ok = bar(arg); 
      } 
      FreeLibrary(pDll); 
     } 
     return ok; 
    } 
} 

그러나, 나는 나중에이 DLL을 호출하는 동안 설정 한 경우 lastError 값에 얻을 필요, 그래서 이것으로 내 코드를 변경 :

class DllAccess 
{ 
    [DllImport("foo.dll", EntryPoint = "bar", CallingConvention = CallingConvention.StdCall, SetLastError = true)] 
    private extern Bool DllBar(Byte arg); // return value indicates whether function call went well or not. 

    Bool Bar(Byte arg) 
    { 
     return DllBar(arg); 
    } 
} 

물론 이것은 훨씬 더 세련되고 언급 한 것처럼 lastError 코드를 설정합니다. 분명히, 내 첫 번째 코드는 런타임에 dll과 함수 호출을 변경할 수있는 가능성을 제공하지만, 지금은 필요하지 않습니다. 그래서 제 질문은 : 제가 확실하다면 다른 dll이나 다른 함수를 사용하지 않을 첫 번째 공식을 사용하는 이유가 있습니까?

답변

4

GetProcAddress를 사용하는 유일한 장점은 함수를 호출 할뿐만 아니라 DLL을 수동으로 언로드 할 수 있으며 런타임에 쉽게 이름을 변경할 수 있다는 것입니다.

그러나 두 번째 옵션은 많은 이점을 제공합니다. "tidier"일뿐만 아니라 데이터 형식 마샬링 대부분을 처리합니다. 이는 특정 API에서 매우 중요합니다.

그렇다면 먼저 나열한 방법을 사용하면 모든 것을 언로드해야합니다. 지금 Bar()를 호출 할 때마다 기본적으로 주소가 누출됩니다 ... 자세한 내용은 FreeLibrary을 참조하십시오.

+0

답장을 보내 주셔서 감사합니다. 내 코드에서 실제로 라이브러리를 생성자에로드하고 소멸자에서 라이브러리를 해제 한 다음 라이브러리를 두 번 이상로드하는 데 문제가 있는지 알지 못했기 때문에 전체를 싱글 톤으로 사용했습니다. 정확함을 기하기 위해 도서관을 무료로 내 게시물을 편집했습니다. – Boris

+0

@Boris :'LoadLibrary'와'FreeLibrary'는 카운팅을 참조하기 때문에 여러 콜이 잘 작동하는 경향이 있습니다. –

+0

"누출 주소"란 무엇을 의미합니까? DLL은 한 번만로드되고 함수의 복사본 하나만 메모리에 있고 대리자는 가비지 수집됩니다. –

2

아마 GetProcAddress의 가장 큰 장점은 DLL의 검색 경로를 제어 할 수 있다는 것입니다. 예를 들어 32 비트 또는 64 비트 버전의 원시 DLL을 자동으로로드 할 수 있습니다. DllImportAttribute을 사용하면이 작업을 수행 할 수 없습니다.

+0

벤 : 그냥 참고하십시오 - 라이브러리를 별도의 경로에두고 런타임에 검색 경로를 변경하여 [DllImport]를 사용하여이 작업을 수행 할 수 있습니다. –

+0

PATH 환경 변수가 엉망입니다. 권장하지 않습니다. http://blogs.msdn.com/b/oldnewthing/archive/2008/12/11/9193695.aspx –