Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Bij het verwerken van gegevens kan de interop-marshaller de gegevens kopiëren of vastzetten die worden verwerkt. Als u de gegevens kopieert, wordt een kopie van gegevens van de ene geheugenlocatie op een andere geheugenlocatie opgeslagen. In de volgende afbeelding ziet u de verschillen tussen het kopiëren van een waardetype en het kopiëren van een type dat wordt doorgegeven door verwijzing van beheerd naar onbeheerd geheugen.
Methodeargumenten die als waarde worden doorgegeven, worden gemarshalled naar on-beheerde code als waarden op de stapel. Het kopieerproces is rechtstreeks. Argumenten die door verwijzing worden doorgegeven, worden als pointers op de stapel geplaatst. Verwijzingstypen worden ook doorgegeven door waarde en door referentie. Zoals in de volgende afbeelding wordt weergegeven, worden verwijzingstypen die als waarde worden doorgegeven, gekopieerd of gefixeerd.
Door te pinnen worden de gegevens tijdelijk vergrendeld op hun huidige geheugenlocatie, zodat ze niet kunnen worden verplaatst door de garbagecollector van de Common Language Runtime. De marshaller maakt gegevens vast om de overhead van het kopiëren te verminderen en de prestaties te verbeteren. Het type van de gegevens bepaalt of deze tijdens het marshallingproces worden gekopieerd of vastgezet. Vastmaken wordt automatisch uitgevoerd tijdens het marshallen voor objecten zoals String, maar u kunt ook handmatig geheugen vastmaken met behulp van de GCHandle klasse.
Geformatteerde Blittable-klassen
Opgemaakte blittable-klassen hebben een vaste indeling (opgemaakt) en algemene gegevensweergave in zowel beheerd als onbeheerd geheugen. Wanneer deze typen marshalling vereisen, wordt een aanwijzer naar het object in de heap rechtstreeks aan de ontvanger doorgegeven. De opgeroepene kan de inhoud van de geheugenlocatie waarnaar de aanwijzer verwijst, wijzigen.
Opmerking
De aangeroepene kan de geheugeninhoud wijzigen als de parameter is gemarkeerd als Out of In/Out. De aangeroepene moet daarentegen voorkomen dat de inhoud wordt gewijzigd wanneer de parameter is ingesteld om over te dragen als In, wat de standaardinstelling is voor geformatteerde blittable-typen. Als u een In-object wijzigt, worden er problemen gegenereerd wanneer dezelfde klasse wordt geëxporteerd naar een typebibliotheek en wordt gebruikt voor het aanroepen van meerdere appartementen.
Niet-blittable klassen opgemaakt
Opgemaakte niet-blittable klassen hebben een vaste indeling, maar de gegevensweergave verschilt tussen beheerd en onbeheerd geheugen. De gegevens kunnen transformatie vereisen onder de volgende voorwaarden:
Als een niet-blittable klasse doorgeven wordt op waarde, ontvangt de ontvanger een pointer naar een kopie van de gegevensstructuur.
Als een niet-belichte klasse op basis van verwijzing wordt aangeduid, ontvangt de aanwijzer een aanwijzer naar een kopie van de gegevensstructuur.
Als het InAttribute kenmerk is ingesteld, wordt deze kopie altijd geïnitialiseerd met de status van het exemplaar, marshalling als dat nodig is.
Als het OutAttribute kenmerk is ingesteld, wordt de status zo nodig altijd terug gekopieerd naar het exemplaar dat wordt geretourneerd.
Als zowel
InAttributealsOutAttributezijn ingesteld, zijn beide kopieën vereist. Als een van beide kenmerken wordt weggelaten, kan de marshaller optimaliseren door een van beide kopieën te elimineren.
Verwijzingstypen
Verwijzingstypen kunnen worden doorgegeven door waarde of door referentie. Wanneer ze als waarde worden doorgegeven, wordt een pointer naar het type op de stack doorgegeven. Wanneer door verwijzing wordt doorgegeven, wordt een aanwijzer naar een aanwijzer naar het type op de stack doorgegeven.
Referentietypen hebben het volgende voorwaardelijke gedrag:
Als een verwijzingstype wordt doorgegeven als waarde en het leden van niet-belittebare typen heeft, worden de typen tweemaal geconverteerd.
Wanneer een argument wordt doorgegeven aan de onbeheerde zijde.
Bij terugkomst van het gesprek.
Om onnodig kopiëren en converteren te voorkomen, worden deze typen ge marshalld als In parameters. U moet de
InAttributeenOutAttributeattributen expliciet toepassen op een argument zodat de aanroeper de wijzigingen kan zien die door de aangeroepene zijn aangebracht.Als een verwijzingstype als waarde wordt doorgegeven en het alleen leden van blittable typen heeft, kan het worden vastgezet tijdens marshalling en worden eventuele wijzigingen die de aangeroepene aan de leden van het type aanbrengt door de aanroeper gezien. Pas
InAttributeenOutAttributeexpliciet toe als u dit specifieke gedrag wilt. Zonder deze directionele kenmerken exporteert de interop-marshaller geen richtingsinformatie naar de typebibliotheek (het wordt als 'In' geëxporteerd, wat de standaardinstelling is) en dit kan problemen veroorzaken met COM cross-apartment marshalling.Als een verwijzingstype door een verwijzing wordt doorgegeven, wordt het standaard als In/Uit geëxporteerd.
System.String en System.Text.StringBuilder
Wanneer gegevens worden gemarshalled naar onbeheerde code door waarde of door verwijzing, kopieert de marshaller de gegevens doorgaans naar een secundaire buffer (mogelijk tekensets converterend tijdens de kopie) en geeft een verwijzing naar de buffer door aan de ontvanger. Tenzij de verwijzing is BSTR toegewezen met SysAllocString, wordt de verwijzing altijd toegewezen aan CoTaskMemAlloc.
Als een optimalisatie, wanneer of String of StringBuilder als waarde worden behandeld (zoals een Unicode-tekenreeks), geeft de marshaller een directe verwijzing aan de aangeroepen functie naar beheerde tekenreeksen in de interne Unicode-buffer door, in plaats van het naar een nieuwe buffer te kopiëren.
Waarschuwing
Wanneer een tekenreeks door waarde wordt doorgegeven, mag de callee nooit de verwijzing wijzigen die door de marshaller is doorgegeven. Hierdoor kan de beheerde heap beschadigd raken.
Wanneer een System.String door verwijzing wordt doorgegeven, kopieert de marshaller de inhoud van de tekenreeks naar een secundaire buffer voordat de aanroep wordt uitgevoerd. Vervolgens wordt de inhoud van de buffer gekopieerd naar een nieuwe tekenreeks bij terugkeer vanuit de aanroep. Deze techniek zorgt ervoor dat de onveranderbare beheerde tekenreeks ongewijzigd blijft.
Wanneer een System.Text.StringBuilder door waarde wordt doorgegeven, geeft de marshaller een verwijzing naar een tijdelijke kopie van de interne buffer van de StringBuilder door aan de aanroeper. De beller en de gebelde moeten akkoord gaan over de grootte van de buffer. De beller is verantwoordelijk voor het creëren van een StringBuilder van voldoende lengte. De ontvanger moet de nodige voorzorgsmaatregelen nemen om ervoor te zorgen dat de buffer niet wordt overschreden.
StringBuilder is een uitzondering op de regel die verwijzingstypen die door de waarde worden doorgegeven, standaard als In parameters worden doorgegeven.
StringBuilder wordt altijd doorgegeven als In/Out.