Not
Åtkomst till denna sida kräver auktorisation. Du kan prova att logga in eller byta katalog.
Åtkomst till denna sida kräver auktorisation. Du kan prova att byta katalog.
För att hålla programmeringsspråket agnostiskt returnerar Windows COM-systemet och många Windows-API:er en heltalstyp med 4 byte som kallas för HRESULT att ange om ett API lyckades eller misslyckades, tillsammans med viss information om felet. Andra värden som måste skickas till anroparen "returneras" via pekarparametrar som fungerar som "out"-parametrar och är vanligtvis den sista parametern i signaturen. Språk som C# och Visual Basic översätter traditionellt en felkod till ett undantag för att matcha hur fel vanligtvis sprids på språket och förväntar sig att interop-metodsignaturer inte ska innehålla HRESULT. Om du vill översätta metodsignaturen till en inhemsk signatur flyttar körmiljön returvärdet för metoden till en ytterligare "out"-parameter med ett ytterligare indirektionslager (med andra ord en pekare till den hanterade signaturens returtyp) och accepterar ett HRESULT returvärde. Om den hanterade metoden returnerar voidläggs ingen ytterligare parameter till och returvärdet blir en HRESULT. Se till exempel följande två C#COM-metoder som översätts till samma interna signatur:
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 i COM
Alla COM-metoder i C# förväntas använda den översatta signaturen som standard. Om du vill använda och exportera metoder utan signaturöversättning och hantering av HRESULT värden lägger du till PreserveSigAttribute i en COM-gränssnittsmetod. När attributet tillämpas på en metod görs ingen översättning till signaturen och undantag genereras inte för misslyckade HRESULT värden. Detta gäller både inbyggd COM och källgenererad COM. Se till exempel följande C#-metodsignatur med ett PreserveSig attribut och dess motsvarande interna signatur.
[PreserveSig]
int Add(int a, int b, out int sum);
HRESULT Add(int a, int b, int* sum);
Detta kan vara användbart om metoden kan returnera olika HRESULT värden som inte är fel, men som måste hanteras på olika sätt. Vissa metoder kan till exempel returnera värdet S_FALSE när en metod inte misslyckas utan bara returnerar partiella resultat och S_OK när den returnerar alla resultat.
PreserveSig med P/Invokes
Attributet DllImportAttribute har också fältet bool PreserveSig som fungerar på samma sätt som PreserveSigAttribute, men som standard true. För att signalera att körningen ska översätta den hanterade signaturen och hantera den HRESULT som returneras, anger du PreserveSig-fältet till false i DllImportAttribute. Titta till exempel på följande signaturer för två P/Invokes till samma interna metod, en med PreserveSig inställd på false och en där den är kvar vid standardvärdet 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);
Anmärkning
Källgenererade P/Invokes, som använder fältet LibraryImportAttribute, har inget PreserveSig fält. Den genererade koden förutsätter alltid att den interna och hanterade signaturen är identiska. Mer information finns i Källgenererade P/Invokes.
Hantera värden manuellt HRESULT
När du anropar en PreserveSig metod som returnerar en HRESULTkan du använda ThrowExceptionForHR -metoden för att utlösa motsvarande undantag om HRESULT det indikerar ett fel. När du implementerar en PreserveSig metod kan du på samma sätt använda GetHRForException metoden för att returnera HRESULT som anger ett motsvarande värde för undantaget.
Marshal HRESULTs som strukturer
När du använder en PreserveSig metod int förväntas vara den hanterade typen för HRESULT. Men om du använder en anpassad 4-bytes struct som returtyp kan du definiera hjälpmetoder och egenskaper som kan förenkla arbetet med HRESULT. Vid inbyggd marshalling fungerar detta automatiskt. Om du vill använda en struct i stället för int som den hanterade representationen av HRESULT i källgenererad marshalling lägger du till MarshalAsAttribute attributet med Error som argument. Förekomsten av det här attributet omtolkar bitar av HRESULT som struct.