Udostępnij za pośrednictwem


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:

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)