Шаг 214.
Microsoft Visual C++ 2010. Язык С/С++. Преобразование между регулируемыми и нерегулируемыми... . Пример 3. Преобразование String^ строки в строку wchar_t
На этом шаге мы приведем программу, реализующую указанное преобразование.
Тип wchar_t - это native-тип символа по таблице Юникода. Этот тип данного отличается от типа char тем, что символ кодируется двумя байтами, а не одним. Класс
String тоже создает строку из Юникод-символов, однако по своему определению относится к managed-типу.
Преобразование, которое мы рассматриваем, фактически переводит Юникод-строку из состояния managed в состояние native. А в этом состоянии со строкой уже можно работать,
применяя обычный указатель *. Юникод-тексты можно вводить в файлы и читать из них соответственно функциями fputws() и fgetws.
Текст программы приведен ниже, а результат - на рисунке 1.
// 214_1.cpp: главный файл проекта.
#include "stdafx.h"
#include <stdio.h> //для printf()
#include <conio.h> //для _getch()
#include <vcclr.h> //для PtrToStringChars()
using namespace System;
using namespace System::Runtime::InteropServices;
#pragma unmanaged
void NativeTakesAString(const wchar_t* p)
{
printf("(native) recieved '%S'\n", p);
}
#pragma managed
void main()
{
String^ s = gcnew String("test string");
pin_ptr<const wchar_t> str = PtrToStringChars(s);
// метод размещает s в управляемой куче и выдает
// native-указатель типа _const_Char_ptr на
// размещенный объект. Этот указатель с помощью оператора
// [cli::]pin_ptr<cv_qualifier type> var = ^initializer;
// преобразуется в тип const wchar_t.
// Здесь:
// cv_qualifier - квалификатор const или квалификатор volatile.
// Квалификатор volatile показывает, что поле может
// модифицироваться многочисленными средами, выполняющимися в
// данный момент, и все изменения данного поля будут
// присутствовать в этом поле. Указатель типа pin_ptr по
// умолчанию имеет квалификатор volatile, поэтому в операторе
// применен квалификатор const, чтобы объект в куче не изменял
// своего значения, а не только место расположения.
// initializer - это ссылочный тип данного: элемент
// managed-массива или любого другого объекта, которому
// вы назначаете native-указатель.
// Метод PtrToStringChars() как раз и выдает такой указатель:
// native-указатель в управляемой (managed) куче.
// type - тип initializer'а. В нашем случае это wchar_t
// var - это имя pin_ptr указателя. В нашем случае это
// str. Т.е. str - это уже native-указатель String в
// управляемой куче.
Console::WriteLine("(managed) passing string to native func...");
// вывод сообщения из managed-функции
NativeTakesAString( str );
// вызов native-функции, которая выдаст native-сообщение
_getch();
}
Архив проекта можно взять
здесь.
Рис.1. Результат преобразования Юникод-строки в native-строку
Здесь применен указатель pin_ptr (указатель от зашкаливания, как определяют его авторы). Это внутренний указатель, который оберегает объект (на который он указывает) от какого-либо
перемещения в управляемой куче (памяти, с которой работает режим CLR): значение указателя не изменяется средой CLR. Такое условие необходимо при передаче адреса
managed-объекта native-функции, потому что этот адрес не должен меняться во время вызова native-функции.
На следующем шаге мы приведем пример программы, выполняющей преобразование строки wchar_t в строку String^.
Предыдущий шаг
Содержание
Следующий шаг