Delen via


Procedure: ANSI-tekenreeksen marshalen met behulp van C++-interop

In dit onderwerp wordt gedemonstreerd hoe ANSI-tekenreeksen kunnen worden doorgegeven met behulp van C++ Interop, maar het .NET Framework String vertegenwoordigt tekenreeksen in Unicode-indeling, dus conversie naar ANSI is een extra stap. Zie de volgende onderwerpen voor samenwerking met andere tekenreekstypen:

In de volgende codevoorbeelden worden de beheerde, onbeheerde #pragma instructies gebruikt om beheerde en onbeheerde functies in hetzelfde bestand te implementeren, maar deze functies werken op dezelfde manier als deze zijn gedefinieerd in afzonderlijke bestanden. Omdat bestanden met alleen niet-beheerde functies niet hoeven te worden gecompileerd met /clr (Common Language Runtime Compilation), kunnen ze hun prestatiekenmerken behouden.

Voorbeeld: ANSI-tekenreeks doorgeven

In het voorbeeld ziet u hoe u een ANSI-tekenreeks doorgeeft van een beheerde naar een niet-beheerde functie met behulp van StringToHGlobalAnsi. Met deze methode wordt geheugen toegewezen aan de niet-beheerde heap en wordt het adres geretourneerd nadat de conversie is uitgevoerd. Dit betekent dat er geen vastmaken nodig is (omdat geheugen op de GC-heap niet wordt doorgegeven aan de onbeheerde functie) en dat de IntPtr die van StringToHGlobalAnsi wordt geretourneerd expliciet moet worden vrijgegeven, anders ontstaat er een geheugenlek.

// MarshalANSI1.cpp
// compile with: /clr
#include <iostream>
#include <stdio.h>

using namespace std;
using namespace System;
using namespace System::Runtime::InteropServices;

#pragma unmanaged

void NativeTakesAString(const char* p) {
   printf_s("(native) received '%s'\n", p);
}

#pragma managed

int main() {
   String^ s = gcnew String("sample string");
   IntPtr ip = Marshal::StringToHGlobalAnsi(s);
   const char* str = static_cast<const char*>(ip.ToPointer());

   Console::WriteLine("(managed) passing string...");
   NativeTakesAString( str );

   Marshal::FreeHGlobal( ip );
}

Voorbeeld: Gegevensverwerking vereist voor toegang tot ANSI-tekstreeks

In het volgende voorbeeld ziet u de gegevensoverdracht die is vereist voor toegang tot een ANSI-tekenreeks in een beheerde functie die wordt aangeroepen door een niet-beheerd functie. De beheerde functie, bij het ontvangen van de systeemeigen tekenreeks, kan deze rechtstreeks gebruiken of converteren naar een beheerde tekenreeks met behulp van de PtrToStringAnsi methode, zoals wordt weergegeven.

// MarshalANSI2.cpp
// compile with: /clr
#include <iostream>
#include <vcclr.h>

using namespace std;

using namespace System;
using namespace System::Runtime::InteropServices;

#pragma managed

void ManagedStringFunc(char* s) {
   String^ ms = Marshal::PtrToStringAnsi(static_cast<IntPtr>(s));
   Console::WriteLine("(managed): received '{0}'", ms);
}

#pragma unmanaged

void NativeProvidesAString() {
   cout << "(native) calling managed func...\n";
   ManagedStringFunc("test string");
}

#pragma managed

int main() {
   NativeProvidesAString();
}

Zie ook

C++ Interop gebruiken (impliciete PInvoke)