Шаг 212.
Microsoft Visual C++ 2010. Язык С/С++. Преобразование между регулируемыми и нерегулируемыми указателями. Пример 1. Перевод строки String^ в ASCII-строку

    На этом шаге мы приведем программу, реализующую указанное преобразование.

    Текст программы приведен ниже, а результат ее работы - на рисунке 1.

// 212_1.cpp: главный файл проекта.

#include "stdafx.h"
#include <stdio.h>

using namespace System;
using namespace System::Runtime::InteropServices;

#pragma unmanaged
// сигнал компилятору, что далее следуют unmanaged-функции, 
// работающие с обычными (native) переменными, которые станут 
// размещаться в неуправляемой куче (памяти), за 
// переполнением которой надо следить самому - 
// вовремя освобождать от занимающих ее объектов

void NativeTakesAString (const char* p) 
{
	printf("(native) received '%s'\n", p);
}
 
#pragma managed
// сигнал компилятору, что далее следуют managed-функции, 
// работающие со средой CLR, в которой переменные станут 
// размещаться в управляемой куче (памяти), за переполнением 
// которой не надо следить самому - среда CLR сама 
// позаботится oб освобождении от занимаемых объектов

int main()
{
	String^ s = gcnew String("sample string");
	IntPtr ip = Marshal::StringToHGlobalAnsi(s);
	// этот метод выделяет для s место в неуправляемой куче 
	// и указатель на место передает в структуру IntPtr. 
	// Указатель имеет тип void, т.е. его еще надо 
	// настроить на конкретный тип данного
	
	const char* str = static_cast<const char*>(ip.ToPointer());
	// кастинг указателя: настройка его на native-тип char* с 
	// помощью оператора static_cast <type-id> (expression). 
	// Теперь указатель str типа char будет настроен в 
	// неуправляемой куче на начало переменной s. 
	// Т.к. s - константа, то у указателя str взят квалификатор 
	// const, говорящий о том, что значение, на которое 
	// указывает указатель, изменять нельзя

	Console::WriteLine("(managed) passing string...");
	// т.к. мы находимся в managed-методе main(), то и 
	// вывод идет по WriteLine()
	
	//вызов native-метода внутри managed-метода
	NativeTakesAString( str ); 
 
	Marshal::FreeHGlobal( ip );
	// этот метод освобождает память, выделенную 
	// StringToHGlobalAnsi(s): это уже неуправляемая 
	// куча, то память надо освобождать самому

	Console::ReadLine();
}
Архив проекта можно взять здесь.


Рис.1. Результат перевода native-строки в managed-строку

    На следующем шаге мы приведем пример программы, переводящей ASCII-строки в String^ строку.




Предыдущий шаг Содержание Следующий шаг