Dela via


Gör så här: Marshalla ANSI-strängar med C++ Interoperabilitet

Det här avsnittet visar hur ANSI-strängar kan skickas med C++ Interop, men .NET Framework String representerar strängar i Unicode-format, så konvertering till ANSI är ett extra steg. Information om hur du samverkar med andra strängtyper finns i följande avsnitt:

I följande kodexempel används de hanterade, ohanterade #pragma-direktiven för att implementera hanterade och ohanterade funktioner i samma fil, men dessa funktioner samverkar på samma sätt om de definieras i separata filer. Eftersom filer som endast innehåller ohanterade funktioner inte behöver kompileras med /clr (Common Language Runtime Compil) kan de behålla sina prestandaegenskaper.

Exempel: Skicka ANSI-sträng

Exemplet visar hur du skickar en ANSI-sträng från en hanterad till en ohanterad funktion med hjälp av StringToHGlobalAnsi. Den här metoden allokerar minne på den ohanterade heapen och returnerar adressen när konverteringen har utförts. Det innebär att ingen fästning krävs (eftersom minnet på GC-heapen inte skickas till den ohanterade funktionen) och att IntPtr som returneras från StringToHGlobalAnsi måste släppas explicit eller resulterar i en minnesläcka.

// 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 );
}

Exempel: Datamarsering krävs för åtkomst till ANSI-sträng

I följande exempel visas den datamarsering som krävs för att komma åt en ANSI-sträng i en hanterad funktion som anropas av en ohanterad funktion. Den hanterade funktionen kan när den ursprungliga strängen tas emot antingen använda den direkt eller konvertera den till en hanterad sträng med hjälp av PtrToStringAnsi-metoden, som visas.

// 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();
}

Se även

Använda C++ Interop (implicit PInvoke)