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.
Systeemeigen functies die tekenreeksen in C-stijl accepteren, kunnen worden aangeroepen met behulp van het CLR-tekenreekstype System::String met behulp van ondersteuning voor .NET Framework Platform Invoke (P/Invoke). We raden u aan om de C++ Interop-functies te gebruiken in plaats van P/Invoke, indien mogelijk. omdat P/Invoke weinig rapportage over compilatiefouten biedt, niet type-veilig is en lastig te implementeren kan zijn. Als de niet-beheerde API is verpakt als een DLL en de broncode niet beschikbaar is, is P/Invoke de enige optie. Anders, zie C++-interop gebruiken (impliciete P/aanroep).
Beheerde en niet-beheerde tekenreeksen worden anders ingedeeld in het geheugen, dus het doorgeven van tekenreeksen van beheerde naar onbeheerde functies vereist dat het MarshalAsAttribute kenmerk de compiler instrueert om de vereiste conversiemechanismen in te voegen voor het correct en veilig verwerken van de tekenreeksgegevens.
Net als bij functies die alleen intrinsieke gegevenstypen gebruiken, DllImportAttribute wordt gebruikt om beheerde toegangspunten in de systeemeigen functies te declareren. Functies die tekenreeksen doorgeven, kunnen een ingang gebruiken voor het String type in plaats van deze invoerpunten te definiëren als tekenreeksen in C-stijl. Met dit type wordt de compiler gevraagd code in te voegen waarmee de vereiste conversie wordt uitgevoerd. Voor elk functieargument in een onbeheerde functie die een tekenreeks gebruikt, gebruikt u het MarshalAsAttribute kenmerk om aan te geven dat het String object als een tekenreeks in C-stijl moet worden doorgegeven aan de systeemeigen functie.
De marshaler omhult de aanroep naar de onbeheerde functie in een verborgen wrapper-routine. De wrapper routine pint en kopieert de beheerde tekenreeks naar een lokaal toegewezen tekenreeks in de onbeheerde context. De lokale kopie wordt vervolgens doorgegeven aan de onbeheerde functie. Wanneer de niet-beheerde functie wordt geretourneerd, verwijdert de wrapper de resource. Of als deze zich op de stapel bevindt, wordt deze vrijgemaakt wanneer de wrapper buiten het bereik komt. De niet-beheerde functie is niet verantwoordelijk voor dit geheugen. De niet-beheerde code maakt en verwijdert alleen geheugen in de heap die is ingesteld door zijn eigen CRT, waardoor er nooit een probleem is met de marshaller die een andere CRT-versie gebruikt.
Als uw onbeheerde functie een tekenreeks retourneert, ofwel als retourwaarde of als een outparameter, kopieert de marshaler deze naar een nieuwe beheerde tekenreeks en geeft het geheugen vervolgens vrij. Zie Default Marshaling Behavior en Marshaling Data with Platform Invoke voor meer informatie.
Voorbeeld
De volgende code bestaat uit een niet-beheerde module en een beheerde module. De niet-beheerde module is een DLL die een functie genaamd TakesAString definieert. 
              TakesAString accepteert een smalle tekenreeks in C-stijl in de vorm van een char*.
// TraditionalDll2.cpp
// compile with: /LD /EHsc
#include <windows.h>
#include <stdio.h>
#include <iostream>
using namespace std;
#define TRADITIONALDLL_EXPORTS
#ifdef TRADITIONALDLL_EXPORTS
#define TRADITIONALDLL_API __declspec(dllexport)
#else
#define TRADITIONALDLL_API __declspec(dllimport)
#endif
extern "C" {
   TRADITIONALDLL_API void TakesAString(char*);
}
void TakesAString(char* p) {
   printf_s("[unmanaged] %s\n", p);
}
De beheerde module is een opdrachtregeltoepassing waarmee de TakesAString functie wordt geïmporteerd, maar wordt gedefinieerd als een beheerde System.String toepassing in plaats van een char*. Het MarshalAsAttribute kenmerk wordt gebruikt om aan te geven hoe de beheerde tekenreeks gemarshaled moet worden wanneer TakesAString wordt aangeroepen.
// MarshalString.cpp
// compile with: /clr
using namespace System;
using namespace System::Runtime::InteropServices;
value struct TraditionalDLL
{
   [DllImport("TraditionalDLL2.dll")]
      static public void
      TakesAString([MarshalAs(UnmanagedType::LPStr)]String^);
};
int main() {
   String^ s = gcnew String("sample string");
   Console::WriteLine("[managed] passing managed string to unmanaged function...");
   TraditionalDLL::TakesAString(s);
   Console::WriteLine("[managed] {0}", s);
}
Met deze techniek wordt een kopie van de tekenreeks gemaakt op de niet-beheerde heap, zodat wijzigingen in de tekenreeks door de systeemeigen functie niet worden weergegeven in de beheerde kopie van de tekenreeks.
Er wordt geen deel van het DLL-bestand blootgesteld aan de beheerde code door de traditionele #include richtlijn. In feite wordt het DLL-bestand alleen tijdens runtime geopend, dus problemen in functies die worden geïmporteerd met behulp DllImport van, worden niet gedetecteerd tijdens het compileren.