Gewusst wie: Marshallen von ANSI-Zeichenfolgen mit C++-Interop
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:
Gewusst wie: Marshallen von Unicode-Zeichenfolgen mit C++-Interop
Gewusst wie: Marshallen von COM-Zeichenfolgen mit C++-Interop
In den folgenden Codebeispielen werden die verwaltet, nicht verwaltet-#pragma-Direktiven verwendet, um verwaltete und nicht verwaltete Funktionen in derselben Datei zu implementieren. Diese Funktionen arbeiten jedoch auf dieselbe Weise zusammen, wenn sie 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 belegt 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();
}