DllImportAttribute 일반 지식 소개
5992 단어 Programme
인용문
DllImportAttribute 속성은 관리되지 않는 함수를 호출하는 사양을 제공합니다.위탁 관리 코드를 P/Invoke 호출할 때 DllImportAttribute 형식은 중요한 역할을 합니다.DllImportAttribute의 주요 역할은 CLR에 호출할 함수를 내보낼 DLL을 표시하는 것입니다.관련 DLL 이름은 DllImportAttribute에 구조 함수 매개 변수로 전달됩니다.
일반 등록 정보 소개
EntryPoint
호출할 DLL 엔트리 포인터의 이름 또는 번호를 지정합니다(기본 엔트리 포인터 이름은 호스팅 메소드의 이름).시퀀스 번호는 #1과 같은 # 기호를 접두어로 합니다. 이 필드를 생략하면 CLR은 DllImportAttribute로 표시됩니다.NET 메서드의 이름입니다. EntryPoint는 DLL 내보내기와 동일한 이름을 가진 외부 호스팅 방법을 원하지 않는 경우 내보낸 DLL 함수의 엔트리 포인트 이름을 나타내는 속성을 설정할 수 있습니다. 같은 비 트랜잭션 함수를 호출하는 두 개의 외부 방법을 정의할 때, 이것은 특히 유용하다.또한 Windows에서는 일련 번호 값을 사용하여 내보낸 DLL 함수에 바인딩할 수도 있습니다. 만약 이렇게 해야 한다면, 예를 들어 #1 또는 #129 의 EntryPoint 값 지시 DLL 에서 위탁 관리 함수가 아닌 번호 값.도식 코드:using System; using System.Runtime.InteropServices; class Example { // Use DllImport to import the Win32 MessageBox function. // Specify the method to import using the EntryPoint field and // then change the name to MyNewMessageBoxMethod. [DllImport("user32.dll", CharSet = CharSet.Auto, EntryPoint = "MessageBox")] public static extern int MyNewMessageBoxMethod(IntPtr hWnd, String text, String caption, uint type); static void Main() { // Call the MessageBox function using platform invoke. MyNewMessageBoxMethod(new IntPtr(0), "Hello World!", "Hello Dialog", 0); } } CharSet 문자열 매개 변수를 방법에 봉인하는 방법을 표시합니다.이름 재정비를 제어합니다. CharSet을 통해 열거된 구성원이 이 필드에서 문자열 매개 변수의 봉송 처리 행위를 지정하고 호출할 입구점 이름을 지정합니다. C# 및 Visual Basic의 기본 열거 멤버는 CharSet입니다.Ansi, C++에 대한 기본 열거 구성원은CharSet입니다.None, CharSet.Ansi 등효. Visual Basic에서 Declare 문을 사용하여 CharSet 필드를 지정할 수 있습니다.ExactSpelling 필드는 호출할 입구점 이름을 결정할 때 CharSet 필드의 행동에 영향을 줍니다. CharSet은 문자 세트의 경우 모든 버전의 Windows에서 작성되지 않습니다.Windows 9x 시리즈는 중요한 유니코드 지원이 부족한 반면, Windows NT 및 Windows CE 시리즈는 처음부터 유니코드를 사용합니다.이러한 운영 체제에서 실행되는 CLR은 String 및 Char 데이터의 내부 표현에 유니코드를 사용합니다.그러나 걱정하지 마십시오. Windows 9x API 함수를 호출하면 CLR이 유니코드에서 ANSI로 변환하는 데 필요한 변환을 자동으로 수행합니다. DLL 함수가 텍스트를 어떤 방식으로도 처리하지 않으면 DllImportAttribute의CharSet 속성을 무시할 수 있습니다.그러나 Char 또는 String 데이터가 등식의 일부일 경우 CharSet 속성을 CharSet으로 설정해야 합니다.Auto。이렇게 하면 CLR이 숙주 OS를 기준으로 적절한 문자 세트를 사용할 수 있습니다.CharSet 속성을 명시적으로 설정하지 않은 경우 기본값은 CharSet입니다.Ansi。이 기본값은 Windows 2000, Windows XP 및 Windows NT의 경우 단점이 있습니다.®에서 인덱스 호출을 하면 텍스트 매개 변수 봉송 처리의 성능에 소극적으로 영향을 줍니다. CharSet을 명시적으로 선택해야 합니다.Ansi 또는 CharSet.유니코드의 CharSet 값은 CharSet을 사용하지 않습니다.Auto의 유일한 경우: 두 Win32 OS 중 하나에 해당하는 내보내기 함수를 명시적으로 지정합니다.ReadDirectoryChangesW API 함수는 Windows NT 기반 운영 체제에만 존재하며 유니코드만 지원합니다.이 경우 CharSet을 명시적으로 사용해야 합니다.Unicode。 Windows API에 문자 세트 관계가 있는지 여부가 명확하지 않은 경우도 있습니다.Platform SDK에서 함수의 C 언어 헤더 파일을 검사하는 것이 틀림없는 확인 방법입니다. 도식 코드: using System; using System.Runtime.InteropServices; class Example { // Use DllImport to import the Win32 MessageBox function. // Specify the method to import using the EntryPoint field and // then change the name to MyNewMessageBoxMethod. [DllImport("user32.dll", CharSet = CharSet.Auto, EntryPoint = "MessageBox")] public static extern int MyNewMessageBoxMethod(IntPtr hWnd, String text, String caption, uint type); static void Main() { // Call the MessageBox function using platform invoke. MyNewMessageBoxMethod(new IntPtr(0), "Hello World!", "Hello Dialog", 0); } } SetLastError 호출자가 속성화된 방법에서 반환되기 전에 SetLastError Win32 API 함수를 호출할지 여부를 나타냅니다.true는 호출자가 SetLastError를 호출할 것을 지시합니다.그렇지 않으면 false입니다. 기본값은 false입니다.런타임 오버레이는 GetLastError를 호출하고 다른 API 호출에 의해 오버레이되지 않도록 반환된 값을 캐시합니다. SetLastError 오류 처리는 매우 중요하지만 프로그래밍을 할 때 자주 잊혀집니다.P/Invoke 호출을 수행하는 경우 관리되는 코드의 Windows API 오류 처리와 예외 사이의 차이점을 처리하는 문제도 있습니다. 자주 사용하는 솔루션은 다음과 같습니다. P/Invoke를 사용하여 Windows API 함수를 호출하고 있는 경우 GetLastError를 사용하여 확장된 오류 정보를 찾으려면 외부 방법의 DllImportAttribute에서 SetLastError 속성을true로 설정해야 합니다.이것은 대부분의 외부 방법에 적용된다.따라서 외부 메서드를 호출할 때마다 API 함수에 의해 설정된 CLR 오류가 캐시됩니다.그리고 포장 방법에서 클래스 라이브러리의 시스템을 호출할 수 있습니다.Runtime.InteropServices.Marshal 유형에 정의된 Marshal.GetLastWin32Error 메서드를 사용하여 캐시의 오류 값을 가져옵니다.또한 API 함수에서 예상되는 오류 값을 확인하고 감지할 수 있는 예외를 발생시킵니다.다른 모든 실패 상황(전혀 예상치 못한 실패 상황 포함)은 System에서 발생합니다.ComponentModel 명칭 공간에 정의된 Win32Exception, Marshal.GetLastWin32Error에서 반환한 값이 전달됩니다. 도식 코드:using System.Runtime.InteropServices; public class Win32 { [DllImport("user32.dll",SetLastError=true)] public static extern int MessageBoxA(int hWnd,String text,String caption,uint type); } CallingConvention 전달 방법의 매개 변수를 지정할 때 사용하는 호출 약정 값입니다.기본값은 CallingConvention입니다.Winapi (Winapi 기본 StdCall 규약) 는 대부분의 경우 가능합니다.이 값은 Windows CE 플랫폼의cdecl 대응. 그러나 이 호출이 작동하지 않으면 Platform SDK의 선언 헤더 파일을 검사하여 호출된 API 함수가 호출 약정 기준에 맞지 않는 이상 API인지 확인할 수 있습니다. 일반적으로 Windows API 함수나 C-런타임 DLL 함수와 같은 네이티브 함수의 호출 규칙은 매개변수를 스레드 스택으로 밀어넣거나 스레드 스택에서 제거하는 방법에 대해 설명합니다. 대부분의 Windows API 함수는 함수의 마지막 매개변수를 스택에 밀어 넣은 다음 호출된 함수가 스택을 정리합니다. 반면 많은 C-런타임 DLL 함수는 메소드 매개변수가 메소드 서명에 나타나는 순서에 따라 스택으로 밀어넣고 스택 정리 작업을 호출자에게 맡기도록 정의됩니다. 다행히도 P/Invoke 호출 작업을 하려면 외부 장치가 호출 약속을 이해하기만 하면 된다.일반적으로 기본값인 CallingConvention.Winapi를 시작하는 것이 최선입니다.그리고 C가 실행될 때 DLL 함수와 소수의 함수 중 약정을 Calling Convention으로 변경해야 할 수도 있습니다.Cdecl。 도식 코드: using System; using System.Runtime.InteropServices; public class LibWrap { // C# doesn't support varargs so all arguments must be explicitly defined. // CallingConvention.Cdecl must be used since the stack is // cleaned up by the caller. // int printf(const char *format [, argument]...) [DllImport("msvcrt.dll", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)] public static extern int printf(String format, int i, double d); [DllImport("msvcrt.dll", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)] public static extern int printf(String format, int i, String s); } public class App { public static void Main() { LibWrap.printf("Print params: %i %f", 99, 99.99); LibWrap.printf("Print params: %i %s", 99, "abcd"); } }