Практическое руководство. Маршалирование строк Юникода с использованием взаимодействия C++
В этом разделе демонстрируется одна из аспектов взаимодействия Visual C++. Дополнительные сведения см. в разделе "Использование взаимодействия C++ (неявное PInvoke)".
В следующих примерах кода используются управляемые неуправляемые директивы #pragma для реализации управляемых и неуправляемых функций в одном файле, но эти функции взаимодействуют одинаково, если они определены в отдельных файлах. Файлы, содержащие только неуправляемые функции, не нужно компилировать с помощью /clr (компиляция clr (компиляция среды clr).
В этом разделе показано, как строки Юникода могут передаваться из управляемой функции в неуправляемую функцию и наоборот. Сведения о взаимодействии с другими типами строк см. в следующих разделах:
Практическое руководство. Маршалинг строк ANSI с использованием взаимодействия C++
Практическое руководство. Маршалинг строк COM с помощью взаимодействия C++
Пример. Передача строки Юникода из управляемой в неуправляемую функцию
Чтобы передать строку Юникода из управляемой в неуправляемую функцию, функцию PtrToStringChars (объявленную в Vcclr.h) можно использовать для доступа к памяти, в которой хранится управляемая строка. Так как этот адрес будет передан в собственную функцию, важно, чтобы память закреплялась с помощью pin_ptr (C++/CLI), чтобы предотвратить перемещение строковых данных, если цикл сборки мусора выполняется во время выполнения неуправляемой функции.
// 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();
}