Шаг 223.
Microsoft Visual C++ 2010. Язык С/С++. Преобразование между ... . Пример 12. Объявление дескрипторов в native-типах

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

    Дескрипторами называют указатели в среде CLR. Именно они указывают на объект в управляемой куче. Напрямую нельзя объявить дескриптор в native-типе. Например, в native-функции вы не можете сделать объявление типа такого:

  String^ s;

    Компилятор вам выдаст ошибку. Файл vcclr.h содержит специальный настраиваемый шаблон gcroot, позволяющий ссылаться на CLR-объекты из C++ кучи, т. е. объекты из неуправляемой кучи могут ссылаться на объекты из управляемой кучи. Тем самым устанавливается связь между различными средами. При этом вам позволяется использовать дескриптор в native-типе (например, в функции) и трактовать его как основной тип.

    Шаблон gcroot создан на основе класса:

  System::Runtime::InteropServices::GCHandle    ,
который обеспечивает дескрипторами объекты в управляемой куче.

    Отметим, что сами дескрипторы автоматически удаляются деструктором класса gcroot только тогда, когда они больше не используются. Их нельзя удалять вручную. Если же вы создаете gcroot-объект в native-куче (т. е. в неуправляемой), то должны сами вызвать оператор delete для освобождения ресурса.

    В режиме исполнения программы поддерживается постоянная связь между дескриптором и CLR-объектом, на который он указывает. Если объект по тем или иным причинам перемещается в куче, дескриптор всегда возвращает новый адрес объекта. Переменная не может получить pin-указатель (предохраняющий объект от перемещения в такой куче), пока она назначена шаблону gcroot.

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

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

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

using namespace System;

// reference_to_value_in_native.cpp 
// compile with: /clr

public value struct V //CLR-структура 
{
	String^ str;
}; 

class Native //native-класс
{
	public:
		//член native-класса - дескриптор v_handle:
		gcroot< V^ > v_handle;
};

void main()
{
	Native native; //native-переменная, объявленная в managed-функции
	V v;	//managed-переменная
	//дескриптору присваивается значение v,
	//т.е. формируется ссылка на managed-структуру, 
	// из которой теперь можно извлекать ее элементы:
	native.v_handle = v;
	native.v_handle->str = "Hello to all";

	Console::WriteLine("String in V: {0}", native.v_handle->str); 
	Console::ReadLine();
}
Архив проекта можно взять здесь.


Рис.1. Работа с дескриптором в native-памяти

    На следующем шаге мы рассмотрим работу с дескриптором в native-функции.




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