Sdílet prostřednictvím


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á voidse žá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 DllImportAttributebool PreserveSig také pole, které funguje podobně PreserveSigAttributejako , 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 falsehodnotou 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.

Viz také