Porady: kierowanie ciągów ANSI za pomocą międzyoperacyjności języka C++
W tym temacie pokazano, jak można przekazywać ciągi ANSI przy użyciu międzyoperacyjności języka C++, ale program .NET Framework String reprezentuje ciągi w formacie Unicode, więc konwersja na ANSI jest dodatkowym krokiem. Aby uzyskać informacje o współdziałaniu z innymi typami ciągów, zobacz następujące tematy:
Instrukcje: przeprowadzanie marshalingu ciągów Unicode za pomocą międzyoperacyjności języka C++
Instrukcje: przeprowadzanie marshalingu ciągów COM za pomocą międzyoperacyjności języka C++
Poniższe przykłady kodu używają zarządzanych, niezarządzanych dyrektyw #pragma do implementowania funkcji zarządzanych i niezarządzanych w tym samym pliku, ale te funkcje współdziałają w taki sam sposób, jeśli są zdefiniowane w oddzielnych plikach. Ponieważ pliki zawierające tylko funkcje niezarządzane nie muszą być kompilowane przy użyciu /clr (kompilacja środowiska uruchomieniowego języka wspólnego), mogą zachować swoje cechy wydajności.
Przykład: Przekazywanie ciągu ANSI
W tym przykładzie pokazano przekazywanie ciągu ANSI z zarządzanej do niezarządzanej funkcji przy użyciu polecenia StringToHGlobalAnsi. Ta metoda przydziela pamięć na stercie niezarządzanej i zwraca adres po wykonaniu konwersji. Oznacza to, że żadne przypinanie nie jest konieczne (ponieważ pamięć na stercie GC nie jest przekazywana do niezarządzanej funkcji) i że zwrócony element IntPtr musi StringToHGlobalAnsi być jawnie zwolniony lub wyniki wycieku pamięci.
// 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 );
}
Przykład: przeprowadzanie marshalingu danych wymaganych do uzyskania dostępu do ciągu ANSI
W poniższym przykładzie pokazano marshaling danych wymagany do uzyskania dostępu do ciągu ANSI w funkcji zarządzanej, która jest wywoływana przez funkcję niezarządzaną. Funkcja zarządzana, po otrzymaniu ciągu natywnego, może używać go bezpośrednio lub konwertować na ciąg zarządzany przy użyciu PtrToStringAnsi metody , jak pokazano.
// 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();
}
Zobacz też
Korzystanie z międzyoperacyjności języka C++ (niejawna funkcja PInvoke)