Gewusst wie: Marshallen von ANSI-Zeichenfolgen mit C++-Interop

In diesem Thema wird veranschaulicht, wie ANSI-Zeichenfolgen mithilfe von C++-Interop übergeben werden können, das .NET Framework String stellt jedoch Zeichenfolgen im Unicode-Format dar. Daher ist die Konvertierung in ANSI ein zusätzlicher Schritt. Die Zusammenarbeit mit anderen Zeichenfolgentypen finden Sie in den folgenden Themen:

In den folgenden Codebeispielen werden die verwalteten, nicht verwalteten #pragma Direktiven verwendet, um verwaltete und nicht verwaltete Funktionen in derselben Datei zu implementieren, diese Funktionen funktionieren jedoch in gleicher Weise, wenn sie in separaten Dateien definiert sind. Da Dateien, die nur nicht verwaltete Funktionen enthalten, nicht mit /clr (Common Language Runtime Compilation) kompiliert werden müssen, können sie ihre Leistungsmerkmale beibehalten.

Beispiel: Übergeben einer ANSI-Zeichenfolge

Das Beispiel veranschaulicht das Übergeben einer ANSI-Zeichenfolge von einer verwalteten an eine nicht verwaltete Funktion mithilfe von StringToHGlobalAnsi. Diese Methode weist Speicher für den nicht verwalteten Heap zu und gibt die Adresse nach dem Ausführen der Konvertierung zurück. Dies bedeutet, dass kein Anheften erforderlich ist (da speicher auf dem GC-Heap nicht an die nicht verwaltete Funktion übergeben wird) und dass der von StringToHGlobalAnsi der IntPtr zurückgegebene Code explizit freigegeben werden muss oder ein Speicherverlust resultiert.

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

Beispiel: Für den Zugriff auf ANSI-Zeichenfolge erforderliche Datenmarsing

Das folgende Beispiel veranschaulicht das Datenmarsing, das für den Zugriff auf eine ANSI-Zeichenfolge in einer verwalteten Funktion erforderlich ist, die von einer nicht verwalteten Funktion aufgerufen wird. Die verwaltete Funktion kann beim Empfangen der nativen Zeichenfolge entweder direkt verwendet oder mithilfe der PtrToStringAnsi Methode in eine verwaltete Zeichenfolge konvertiert werden, wie gezeigt.

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

Siehe auch

Verwenden von C++-Interop (implizites PInvoke)