다음을 통해 공유


.NET interop의 암시적 메서드 서명 변환

프로그래밍 언어에 구애받지 않기 위해 Windows COM 시스템과 많은 Windows API는 API의 성공 또는 실패 여부와 실패에 대한 일부 정보를 나타내는 HRESULT(이)라는 4바이트 정수 형식을 반환합니다. 호출자에게 전달해야 하는 다른 값은 "out" 매개 변수로 작동하는 포인터 매개 변수를 통해 "반환"되며, 일반적으로 서명의 마지막 매개 변수입니다. C# 및 Visual Basic과 같은 언어는 일반적으로 실패가 언어로 전파되는 방식과 일치하도록 오류 코드를 예외로 변환하며, interop 메서드 서명에 HRESULT이(가) 포함되지 않을 것으로 예상합니다. 메서드 서명을 네이티브 서명으로 변환하기 위해 런타임은 메서드의 반환 값을 간접 참조 수준이 하나 더 있는 추가 "out" 매개 변수로 이동하고(즉, 관리되는 서명의 반환 형식에 대한 포인터로 만듦) HRESULT 반환 값을 가정합니다. 관리되는 메서드가 void을(를) 반환하면 추가 매개 변수가 추가되지 않고, 반환 값은 HRESULT이(가) 됩니다. 예를 들어 동일한 네이티브 서명으로 변환되는 다음 두 개의 C# COM 메서드를 살펴보세요.

int Add(int a, int b);

void Add(int a, int b, out int sum);
HRESULT Add(int a, int b, /* out */ int* sum);

COM의 PreserveSig

C#의 모든 COM 메서드는 기본적으로 번역된 서명을 사용해야 합니다. HRESULT 값에 대한 서명 변환과 처리 없이 메서드를 사용하고 내보내려면 COM 인터페이스 메서드에 PreserveSigAttribute을(를) 추가합니다. 특성이 메서드에 적용되면 서명에 대한 변환이 수행되지 않으며 실패한 HRESULT 값에 대한 예외가 throw되지 않습니다. 이는 기본 제공 COM과 소스 생성 COM 모두에 적용됩니다. 예를 들어 PreserveSig 특성이 있는 다음 C# 메서드 서명과 상응하는 네이티브 서명을 살펴보세요.

[PreserveSig]
int Add(int a, int b, out int sum);
HRESULT Add(int a, int b, int* sum);

이는 메서드가 실패는 아니지만 다르게 처리해야 하는 다른 HRESULT 값을 반환할 경우에 유용할 수 있습니다. 예를 들어 일부 메서드는 메서드가 실패하지 않고 부분 결과만 반환하는 경우 S_FALSE 값을 반환하고 모든 결과를 반환하는 경우 S_OK 값을 반환할 수도 있습니다.

P/Invokes가 있는 PreserveSig

DllImportAttribute 특성에는 PreserveSigAttribute과(와) 비슷하게 작동하는 bool PreserveSig 필드도 있지만 기본값은 true입니다. 런타임에서 관리되는 서명을 변환하고 반환되는 HRESULT 서명을 처리해야 함을 나타내려면 DllImportAttribute에서 PreserveSig 필드를 false(으)로 설정합니다. 예를 들어 동일한 네이티브 메서드에 대한 두 P/Invokes의 다음 서명을 보면, PreserveSig이(가) 있는 하나는 false(으)로 설정되고 다른 하나는 기본값 true(으)로 남아 있습니다.

[DllImport("shlwapi.dll", EntryPoint = "SHAutoComplete", ExactSpelling = true, PreserveSig = false)]
public static extern void SHAutoComplete(IntPtr hwndEdit, SHAutoCompleteFlags dwFlags);

[DllImport("shlwapi.dll", EntryPoint = "SHAutoComplete", ExactSpelling = true)]
public static extern int SHAutoCompleteHRESULT(IntPtr hwndEdit, SHAutoCompleteFlags dwFlags);

참고 항목

LibraryImportAttribute(을)를 사용하는 소스 생성 P/Invokes는 PreserveSig 필드가 없습니다. 생성된 코드는 항상 네이티브 서명과 관리되는 서명이 동일하다고 가정합니다. 자세한 내용은 소스 생성 P/Invokes를 참조하세요.

수동으로 HRESULT 값 처리

HRESULT을(를) 반환하는 PreserveSig 메서드를 호출할 때 HRESULT이(가) 오류를 나타내는 경우 ThrowExceptionForHR 메서드를 사용하여 해당 예외를 throw할 수 있습니다. 마찬가지로 PreserveSig 메서드를 구현할 때 GetHRForException 메서드를 사용하여 예외에 해당하는 값을 나타내는 HRESULT을(를) 반환할 수 있습니다.

HRESULT를 구조체로 마샬링

PreserveSig 메서드를 사용하는 경우 int은(는) HRESULT에 대한 관리되는 형식이어야 합니다. 하지만 사용자 지정 4바이트 구조체를 반환 형식으로 사용하면 도우미 메서드와 속성을 정의하여 HRESULT 작업을 간소화할 수 있습니다. 기본 제공 마샬링에서는 자동으로 작동합니다. 소스 생성 마샬링에서 HRESULT의 관리되는 표현으로 int 대신 구조체를 사용하려면 Error이(가) 있는 MarshalAsAttribute 특성을 인수로 추가합니다. 이 특성이 있으면 HRESULT 비트가 구조체로 다시 해석됩니다.

참고 항목