Поделиться через


Практическое руководство. Маршалинг строк ANSI с использованием взаимодействия C++

Этот раздел рассматривает способ передачи строк ANSI с помощью взаимодействия C++. Преобразование строк в ANSI является дополнительным шагом, поскольку класс String платформы .NET Framework представляет строки в формате Юникода. Дополнительные сведения о взаимодействии с другими строковыми типами см. в следующих разделах:

В следующем примере кода используются директивы #pragma managed, unmanaged, которые встраивают управляемые и неуправляемые функции в один файл. Эти функции также взаимодействуют в случае их распределения в отдельные файлы. Поскольку файлы, содержащие только неуправляемые функции, не требуют компиляции с /clr (компиляция CLR), они сохраняют определенные показатели производительности.

Пример

В следующем примере демонстрируется передача строк ANSI из управляемой функции в неуправляемую с помощью StringToHGlobalAnsi. Этот метод распределяет память в неуправляемых кучах и возвращает адрес после выполнения преобразования. Это означает, что функция закрепления не требуется (поскольку память в куче сборки мусора не передается в неуправляемую функцию) и что IntPtr, возвращенный с StringToHGlobalAnsi, должен быть явно освобожден или возникнет утечка памяти.

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

На следующем примере демонстрируется маршалинг данных, необходимый для доступа к строке ANSI в управляемой функции, вызываемой неуправляемой функцией. После получения машинной строки управляемая функция может использовать строку без изменений или преобразовать ее в управляемую строку с помощью метода PtrToStringAnsi, как показано ниже.

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

См. также

Ссылки

Использование взаимодействия языка C++ (неявный PInvoke)