Implicitní překlady podpisů metod v interoperabilitě .NET
Aby byl programovací jazyk nezávislý, systém Windows COM a mnoho rozhraní API systému Windows vrátí 4 bajtový celočíselnou typ, který HRESULT
označuje, zda bylo rozhraní API úspěšné nebo neúspěšné, spolu s některými informacemi o selhání. Další hodnoty, které je třeba volajícímu předat, jsou "vráceny" prostřednictvím parametrů ukazatele, které fungují jako "out" parametry a obvykle jsou posledním parametrem v podpisu. Jazyky, jako je C# a Visual Basic, tradičně překládají kód selhání na výjimku, aby odpovídaly způsobu šíření selhání v jazyce a očekávají, že podpisy metod vzájemné spolupráce nezahrnou HRESULT
. Pokud chcete přeložit podpis metody na nativní podpis, modul runtime přesune návratovou hodnotu metody do dalšího parametru "out" s další úrovní nepřímých výrazů (jinými slovy, vytvoří ukazatel na návratový typ spravovaného podpisu) a předpokládá návratovou HRESULT
hodnotu. Pokud spravovaná metoda vrátí , nepřidá void
se žádný další parametr a návratová hodnota se stane HRESULT
. Podívejte se například na následující dvě metody modelu COM jazyka C#, které se překládají na stejný nativní podpis:
int Add(int a, int b);
void Add(int a, int b, out int sum);
HRESULT Add(int a, int b, /* out */ int* sum);
PreserveSig v modelu COM
Očekává se, že všechny metody MODELU COM v jazyce C# budou ve výchozím nastavení používat přeložený podpis. Chcete-li použít a exportovat metody bez překladu podpisu a zpracování HRESULT
hodnot, přidejte PreserveSigAttribute metodu rozhraní MODELU COM. Při použití atributu na metodu se do podpisu neprovede žádný překlad a výjimky se nevyvolají kvůli neúspěšným HRESULT
hodnotám. To platí pro předdefinované com i zdrojové com. Podívejte se například na následující podpis metody jazyka C# s atributem PreserveSig
a odpovídajícím nativním podpisem.
[PreserveSig]
int Add(int a, int b, out int sum);
HRESULT Add(int a, int b, int* sum);
To může být užitečné, pokud metoda může vrátit různé HRESULT
hodnoty, které nejsou selhání, ale musí se zpracovat jinak. Některé metody můžou například vrátit hodnotu S_FALSE
, když metoda selže, ale vrátí pouze částečné výsledky a S_OK
když vrátí všechny výsledky.
PreserveSig
s voláními nespravovaného kódu
Atribut DllImportAttribute má bool PreserveSig
také pole, které funguje podobně PreserveSigAttribute
jako , ale výchozí hodnota true
. Chcete-li označit, že modul runtime by měl přeložit spravovaný podpis a zpracovat vrácený HRESULT
podpis, nastavte PreserveSig
pole na false
hodnotu v objektu DllImportAttribute
. Podívejte se například na následující podpisy dvou volání P/Invoke pro stejnou nativní metodu, jednu s PreserveSig
nastavenou false
hodnotou a druhou, která je ponechána na výchozí true
hodnotě.
[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);
Poznámka:
Zdrojové volání nespravovaných volání, která používají LibraryImportAttributepole , nemají žádné PreserveSig
pole. Vygenerovaný kód vždy předpokládá, že nativní a spravovaný podpis jsou identické. Další informace naleznete v tématu Zdrojové vygenerované volání nespravovaného kódu.
Ruční zpracování HRESULT
hodnot
Při volání PreserveSig
metody, která vrací HRESULT
, můžete použít metodu ThrowExceptionForHR k vyvolání odpovídající výjimky, pokud HRESULT
indikuje selhání. Podobně při implementaci PreserveSig
metody můžete použít metodu GetHRForException k vrácení HRESULT
, která označuje odpovídající hodnotu výjimky.
Zařazování HRESULTs jako struktury
Při použití PreserveSig
metody se očekává, int
že se jedná o spravovaný typ pro HRESULT
. Použití vlastní 4bajtů struktury jako návratový typ umožňuje definovat pomocné metody a vlastnosti, které mohou zjednodušit práci s HRESULT
. V integrovaném zařazování to funguje automaticky. Chcete-li místo spravované reprezentace HRESULT
ve zdrojovém generovaném zařazování použít strukturuint
, přidejte MarshalAsAttribute atribut jako Error argument. Přítomnost tohoto atributu reinterpretuje bity objektu HRESULT
jako strukturu.