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


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

В этом разделе продемонстрирован еще один аспект возможностей взаимодействия Visual C++. Дополнительные сведения см. в разделе Использование взаимодействия языка C++ (неявный PInvoke).

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

В этом разделе показано, как можно передать строки Юникода от управляемой к управляемой функции и наоборот. Дополнительные сведения о взаимодействии с другими строковыми типами см. в следующих разделах:

Пример

Для передачи строки Юникода от управляемой функции к неуправляемой можно воспользоваться функцией PtrToStringChars (объявленной в Vcclr.h) для доступа к памяти, где хранится управляемая строка. Поскольку этот адрес будет передан встроенной функции, важно, чтобы память была закреплена с помощью pin_ptr во избежание перемещения строковых данных в случае запуска цикла сбора мусора во время выполнения неуправляемой функции.

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

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

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

См. также

Ссылки

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