Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
4 сем Инфа готово.docx
Скачиваний:
24
Добавлен:
04.06.2015
Размер:
255.66 Кб
Скачать

Вопрос 8. Взаимодействие с неуправляемым кодом

Как вы, наверное, догадались, неуправляемым (unmanaged code) называется код, который не находится под надзором .NET. Поясним: этот код тоже запускается средствами .NET. Однако у неуправляемого кода нет тех преимуществ, которыми обладает управляемый: сбора мусора, унифицированной системы типов и метаданных. Вы спрашиваете, зачем запускать неуправляемый код в среде .NET? Правильно, без особой нужды этого делать не стоит. Однако вы пойдете на это, когда у вас не будет другого выхода. Вот несколько ситуаций, которые показывают, что можно поблагодарить Microsoft за то, что в .NET заложена эта особенность.

Управляемый код, вызывающий функции неуправляемых DLL Допустим, вашему приложению нужно работать с DLL, написанной на С, а компания, создавшая эту библиотеку, пока не адаптировала ее для технологии .NET. В этом случае вам придется по-прежнему вызывать эту DLL из .NET-приложения.

Управляемый код, использующий компоненты СОМ По той же причине, по какой нужно вызывать из своего .NET-приложения функции из DLL, написанной на С, вам требуется продолжать поддержку компонентов СОМ. Выход в том, чтобы создать .NET-оболочку для компонента СОМ так, чтобы управляемый клиент полагал, будто он работает с .NET-классом.

Неуправляемый код, использующий .NET-службы Здесь противоположная проблема: вам нужен доступ к .NET из неуправляемого кода. Она решается с помощью обратного подхода: клиент СОМ вводится в заблуждение, будто он работает с СОМ-сервером, который на самом деле является .NET-службой того же вида.

С# позволяет программистам писать то, что называется "опасный кодом" (unsafecode). Опасный код — это код, который не плохо написан, а код, который не выполняется под полным управлением системыCommonLanguageRuntime(CLR). С этой точки зрения весь код наC\C++ "опасен". Нет проверок на границы массива, нет автоосвобождени памяти и так далее. Язык С# обычно используется для создания управляемого кода. Однако можно написать и "неуправляемый" код, который не подчиняется тем же средствам управления и ограничениям, налагаемым на управляемый код. Такой код называется "опасным", поскольку невозможно проконтролировать невыполнение им опасных действий. Таким образом, термин опасный не означает, что коду присуща некорректность. Он просто означает возможность выполнения действий, которые не являются предметом управления системыCLR.

Основное различие между указателями в C\C++ и ссылками вC# заключается в том, что указатель может указывать на что угодно в памяти, а ссылка всегда указывает на объект "своего" типа.

Но если указатель может указывать на что угодно, возможно неправильное его использование. Кроме того, работая с указателями, можно легко внести в код ошибку, которую будет трудно отыскать. Вот почему С# не поддерживает указатели при создании управляемого кода. Теме не менее указатели существуют, причем для некоторых типов программ (например, системных утилит) они не просто полезны, они — необходимы, и С# позволяет (что поделаешь) программистам создавать их и использовать. Однако все операции с указателями должны быть отмечены как "опасные", поскольку они выполняются вне управляемого контекста. Объявление и использование указателей в С# происходит аналогично тому, как это делается в C/C++ (если вы знаете, как использовать указатели вC/C++, можете так же работать с ними и в С#). Но помните: особенность С# — создание управляемого кода. Его способность поддерживать неуправляемый код позволяет применять Сопрограммы к задачам специальной категории. Но такое С#- рограммирование уже не попадает под определение стандартного. И в самом деле, чтобы скомпилировать неуправляемый код, необходимо использовать опцию компилятора /unsafe.

Создаём проект, заходим в свойства нашего ConsoleApplication, там кликаем вкладкуBuild, и выбираем галкуAllowunsafecode

Пример:

// Демонстрация использования указателей и

// ключевого слова unsafe.

usingSystem;

classUnsafeCode

{

// Отмечаем метод Main() как "опасный",

unsafe public static void Main()

{

intcount= 99;

int*p; // Создаем указатель наint-значение.

р = &count; // Помещаем адрес переменнойcountв указатель р.

Console.WriteLine("Начальное значение переменнойcountразно " + *p);

*р = 10; // Присваиваем значение 10 переменной countчерез указатель р.

Console.WriteLine("Новое значение переменнойcountравно " + *р);

}

}

// В общем все как в старом добром C.

При работе с указателями зачастую используется модификатор fixed. Он предотвращает удаление управляемых переменных системой сбора мусора. Это необходимо в том случае, если, например, указатель ссылается на какое-нибудь поле в объекте класса. Поскольку указатель "ничего не знает" о действиях "сборщика мусора", то в случае удаления такого объекта этот указатель будет указывать на неверный объект.

Формат применения модификатора fixedтаков:

fixed(type*p= &var) {

// Использование зафиксированного объекта.

}

Вы помните, что в C# строки нельзя менять. А вот мы попробуем:

usingSystem;

classUnfix

{

unsafe public static void Main()

{

string Str = "С# рулит!";

fixed (char* p = Str)

{

*(p + 1) = ' ';

}

Console.WriteLine(Str);

}

}

Как видите, мы производили манипуляции с объектом типа string. А он ведь мог за это время удалиться, что привело бы к некорректному обращению к высвобожденной памяти, а это как помните ещё изCочень черевато. Используяfixedмы оградили объектStrот сборщика мусора.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]