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

Aktualisiert: November 2007

In diesem Beispiel wird gezeigt, wie ANSI-Zeichenfolgen mit C++-Interop übergeben werden. .NET Framework String stellt Zeichenfolgen jedoch im Unicode-Format dar, sodass die Konvertierung in ANSI einen zusätzlichen Schritt darstellt. Informationen zur Interoperation mit anderen Zeichenfolgentypen finden Sie in den folgenden Themen:

In den folgenden Codebeispielen werden die managed, unmanaged-#pragma-Direktiven verwendet, um verwaltete und nicht verwaltete Funktionen in derselben Datei zu implementieren. Diese Funktionen können jedoch auch in separaten Dateien definiert werden. Da Dateien, die lediglich nicht verwaltete Funktionen enthalten, nicht mit /clr (Common Language Runtime-Kompilierung) kompiliert werden müssen, behalten diese ihre Leistungsmerkmale bei.

Beispiel

In diesem Beispiel wird die Übergabe einer ANSI-Zeichenfolge von einer verwalteten Funktion an eine nicht verwaltete Funktion mithilfe von StringToHGlobalAnsi dargestellt. Durch diese Methode wird Arbeitsspeicher auf dem nicht verwalteten Heap reserviert und die Adresse nach Durchführen der Konvertierung zurückgegeben. Aus diesem Grund ist keine Fixierung erforderlich, denn der Speicher auf dem GC-Heap wird nicht an die nicht verwaltete Funktion übergeben, und der von StringToHGlobalAnsi zurückgegebene IntPtr muss explizit freigegeben werden, da sonst Memory Leakage auftritt.

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

Im folgenden Beispiel wird das Datenmarshalling dargestellt, das für den Zugriff auf eine ANSI-Zeichenfolge in einer verwalteten Funktion erforderlich ist, die von einer nicht verwalteten Funktion aufgerufen wird. Die verwaltetete Funktion kann die empfangene sytemeigene Zeichenfolge sofort verwenden oder mithilfe der PtrToStringAnsi-Methode wie dargestellt in eine verwaltete Zeichenfolge konvertieren.

// 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

Referenz

Verwenden von C++-Interop (implizites PInvoke)