На этом шаге мы приведем программу, реализующую указанное преобразование.
Текст программы приведен ниже, а результат ее работы - на рисунке 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^ строку.