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.
När man hanterar data kan interop-marshal kopiera eller låsa data som hanteras. När du kopierar data placeras en kopia av data från en minnesplats på en annan minnesplats. Följande bild visar skillnaderna mellan att kopiera en värdetyp och kopiera en typ som skickas med referens från hanterat till ohanterat minne.
Metodargument som skickas genom värde överförs till icke-hanterad kod som värden på stacken. Kopieringsprocessen är direkt. Argument som passeras som referens skickas som pekare på stacken. Referenstyper skickas också genom värde och referens. Som följande bild visar, referenstyper som skickas som värde kopieras eller fästs.
När du fäster tillfälligt låss data på den aktuella minnesplatsen, vilket förhindrar att de flyttas av common language runtimes skräpinsamlare. Marshaller fäster data för att minska kostnaderna för kopiering och förbättra prestanda. Typen av data avgör om de kopieras eller fästs under marshallingprocessen. Fästning utförs automatiskt under marshalling för objekt som String, men du kan också fästa minne manuellt med hjälp av GCHandle klassen.
Formaterade blittbara klasser
Formaterade blittable-klasser har fast layout (formaterad) och gemensam datarepresentation i både hanterat och ohanterat minne. När dessa typer kräver marshalling skickas en pekare till objektet i heapen direkt till mottagaren. Anropare kan ändra innehållet på minnesplatsen som refereras av pekaren.
Anmärkning
Anropare kan ändra minnesinnehållet om parametern är markerad som Out eller In/Out. Anropare bör däremot undvika att ändra innehållet när parametern är inställd på marshal som In, vilket är standardvärdet för formaterade blittable-typer. Att ändra ett In-objekt genererar problem när samma klass exporteras till ett typbibliotek och används för att göra anrop mellan lägenheter.
Formaterade icke-blittable-klasser
Formaterade icke-blittable-klasser har fast layout (formaterad) men datarepresentationen skiljer sig i hanterat och ohanterat minne. Data kan kräva transformering under följande villkor:
Om en icke-blittable-klass ordnas efter värde, tar anropare emot en pekare till en kopia av datastrukturen.
Om en icke-blittable-klass överförs via referens, får den som anropas en pekare till en pekare till en kopia av datastrukturen.
InAttribute Om attributet anges initieras alltid den här kopian med instansens tillstånd, och serialisering sker efter behov.
Om OutAttribute attributet är inställt kopieras tillståndet alltid tillbaka till instansen vid retur, med nödvändig serialisering.
Om både
InAttributeochOutAttributeanges krävs båda kopiorna. Om något av attributen utelämnas kan marshallern optimera genom att eliminera någon av kopierna.
Referenstyper
Referenstyper kan skickas som värde eller som referens. När de ges som värde, skickas en pekare till en typ på stacken. När den skickas med referens, skickas en pekare till en pekare till typen i stacken.
Referenstyper har följande villkorsstyrda beteende:
Om en referenstyp passeras som värde och har icke-blittable-typers medlemmar, konverteras typerna två gånger:
När ett argument skickas till den ohanterade sidan.
Vid retur från samtalet.
För att undvika onödig kopiering och konvertering ordnas dessa typer som In-parametrar. Du måste uttryckligen tillämpa attributen
InAttributeochOutAttributepå ett argument för att anroparen ska kunna se ändringar som gjorts av anroparen.Om en referenstyp skickas som värde och den bara har medlemmar av blittable-typer, kan den fästas under marshalling, och alla ändringar som görs i medlemmarna av typen av mottagaren syns av anroparen. Använd
InAttributeochOutAttributeexplicit om du vill ha det här beteendet. Utan dessa riktningsattribut exporterar interop-marshaller inte riktningsinformation till typbiblioteket (det exporteras som In, vilket är standard) och detta kan orsaka problem med COM-marshalling mellan olika tråddomäner.Om en referenstyp skickas som referens, kommer den att hanteras som in/ut som standardinställning.
System.String och System.Text.StringBuilder
När data är ordnade till ohanterad kod efter värde eller referens kopierar marshaller vanligtvis data till en sekundär buffert (eventuellt konverterar teckenuppsättningar under kopian) och skickar en referens till bufferten till anroparen. Om referensen inte är allokerad BSTR med SysAllocString allokeras referensen alltid med CoTaskMemAlloc.
Som en optimering när antingen String eller StringBuilder ordnas efter värde (till exempel en Unicode-teckensträng) skickar marshallern anroparen en direktpekare till hanterade strängar i den interna Unicode-bufferten i stället för att kopiera den till en ny buffert.
Försiktighet
När en sträng skickas som värde får mottagaren aldrig ändra referensen som skickas av marshallern. Om du gör det kan den hanterade högen skadas.
När en System.String skickas med referens kopierar marshaller innehållet i strängen till en sekundär buffert innan anropet görs. Sedan kopieras innehållet i bufferten till en ny sträng vid retur från anropet. Den här tekniken säkerställer att den hanterade oföränderliga strängen förblir oförändrad.
När ett System.Text.StringBuilder överförs som värde, skickar marshaller en referens till en tillfällig kopia av den interna bufferten av StringBuilder till anroparen. Anroparen och mottagaren måste komma överens om buffertens storlek. Anroparen ansvarar för att skapa en StringBuilder med tillräcklig längd. Anropare måste vidta nödvändiga försiktighetsåtgärder för att säkerställa att bufferten inte överskrids.
StringBuilder är ett undantag från regeln att referenstyper som överförs som värde som standard överförs som In-parametrar.
StringBuilder skickas alltid som In/Out.