Gewusst wie: Marshallen von Unicode-Zeichenfolgen mit C++-Interop
In diesem Thema wird ein Facet der Visual C++-Interoperabilität veranschaulicht. Weitere Informationen finden Sie unter Using C++ Interop (Implicit PInvoke).
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. Dateien, die nur nicht verwaltete Funktionen enthalten, müssen nicht mit /clr (Common Language Runtime Compilation) kompiliert werden.
In diesem Thema wird veranschaulicht, wie Unicode-Zeichenfolgen von einer verwalteten an eine nicht verwaltete Funktion übergeben werden können und umgekehrt. Informationen zur Interoperabilität mit anderen Zeichenfolgentypen finden Sie in den folgenden Themen:
Vorgehensweise: Marshallen von ANSI-Zeichenfolgen mit C++-Interop
Vorgehensweise: Marshallen von COM-Zeichenfolgen mit C++-Interop
Beispiel: Übergeben einer Unicode-Zeichenfolge von verwalteter zu nicht verwalteter Funktion
Um eine Unicode-Zeichenfolge von einer verwalteten an eine nicht verwaltete Funktion zu übergeben, kann die PtrToStringChars-Funktion (deklariert in Vcclr.h) für den Zugriff im Speicher verwendet werden, in dem die verwaltete Zeichenfolge gespeichert ist. Da diese Adresse an eine systemeigene Funktion übergeben wird, ist es wichtig, dass der Speicher mit pin_ptr (C++/CLI) angeheftet wird, um zu verhindern, dass die Zeichenfolgendaten verschoben werden, sollte ein Garbage Collection-Zyklus ausgeführt werden, während die nicht verwaltete Funktion ausgeführt wird.
// MarshalUnicode1.cpp
// compile with: /clr
#include <iostream>
#include <stdio.h>
#include <vcclr.h>
using namespace std;
using namespace System;
using namespace System::Runtime::InteropServices;
#pragma unmanaged
void NativeTakesAString(const wchar_t* p) {
printf_s("(native) received '%S'\n", p);
}
#pragma managed
int main() {
String^ s = gcnew String("test string");
pin_ptr<const wchar_t> str = PtrToStringChars(s);
Console::WriteLine("(managed) passing string to native func...");
NativeTakesAString( str );
}
Beispiel: Für den Zugriff auf Unicode-Zeichenfolge erforderliche Datenmarsing
Im folgenden Beispiel wird das Datenmarsing veranschaulicht, das für den Zugriff auf eine Unicode-Zeichenfolge in einer verwalteten Funktion erforderlich ist, die von einer nicht verwalteten Funktion aufgerufen wird. Die verwaltete Funktion konvertiert sie beim Empfangen der systemeigenen Unicode-Zeichenfolge mithilfe der PtrToStringUni Methode in eine verwaltete Zeichenfolge.
// MarshalUnicode2.cpp
// compile with: /clr
#include <iostream>
using namespace std;
using namespace System;
using namespace System::Runtime::InteropServices;
#pragma managed
void ManagedStringFunc(wchar_t* s) {
String^ ms = Marshal::PtrToStringUni((IntPtr)s);
Console::WriteLine("(managed) received '{0}'", ms);
}
#pragma unmanaged
void NativeProvidesAString() {
cout << "(unmanaged) calling managed func...\n";
ManagedStringFunc(L"test string");
}
#pragma managed
int main() {
NativeProvidesAString();
}