Российский Государственный Технологический Университет им. К.Э. Циолковского
Опубликован: 02.03.2007 | Доступ: свободный | Студентов: 5678 / 802 | Оценка: 3.96 / 3.45 | Длительность: 27:04:00
ISBN: 978-5-9556-0086-4
Лекция 14:

Совмещение управляемого и неуправляемого кодов

< Лекция 13 || Лекция 14: 12345 || Лекция 15 >
Аннотация: .NET появилась не на пустом месте. Вновь разрабатываемый управляемый код вынужден взаимодействовать с существующим неуправляемым программным кодом. Поэтому на платформе .NET предусмотрены различные сценарии установления взаимодействия между управляемым и неуправляемым кодами. О них рассказанно в этой лекции

Программный код, выполняющийся под управлением CLR, называется управляемым кодом.

Программный код, выполняющийся вне среды выполнения CLR, называется неуправляемым кодом.

Примеры неуправляемого программного кода:

  • функции Win32 API;
  • компоненты COM;
  • интерфейсы ActiveX.

.NET появилась не на пустом месте. Вновь разрабатываемый управляемый код вынужден взаимодействовать с существующим неуправляемым программным кодом. Поэтому на платформе .NET предусмотрены различные сценарии установления взаимодействия между управляемым и неуправляемым кодами. Microsoft .NET Framework обеспечивает взаимодействие с компонентами COM, службами COM+, внешними библиотеками типов и многими службами операционной системы.

CLR скрывает имеющиеся в управляемой и неуправляемой моделях различия. Проблемы, связанные с типами данных, механизмами обработки ошибок и т. д. в управляемой и неуправляемой моделях, решаются CLR "незаметно" как для вызывающей стороны (клиента), так и для вызываемой стороны (сервера). Таким образом, организация взаимодействия между управляемым и неуправляемым кодом выглядит проще, чем могло быть...

C++ .NET. Совмещение управляемого и неуправляемого кодов

Реализованные в .NET языки программирования позволяют создавать управляемый код, который может взаимодействовать с неуправляемыми библиотеками Win32 и компонентами на основе модели компонентных объектов Microsoft (COM).

Язык программирования C++ .NET является единственным, который позволяет создавать как управляемый, так и неуправляемый код. Это дает возможность не только использовать неуправляемый библиотечный код, но и смешивать управляемый и неуправляемый коды в одном приложении.

В приводимых ниже примерах кроме языка программирования C# будет использоваться язык C++.

Управляемый код. Осознать разницу

Первый шаг тривиален. Создается C++ Win32 Console Project, то есть Неуправляемое Консольное Приложение на C++. Последняя версия Visual Studio .NET 2005 позволяет в широких пределах смешивать управляемый и неуправляемый коды.

// Транслятору задали опцию /clr.
 // Эта опция преобразует все объявляемые в программе типы.
 // От имени объекта элементарного типа (например, int) можно
 // вызвать методы базового класса object.
 // Но только вызываются они лишь из фрагментов управляемого 
кода.
 // Иначе – сообщение транслятора:
 // ... managed type or function cannot be used in an unmanaged function

 #include "stdafx.h"

 #include <iostream>
 using namespace std;

 #using <mscorlib.dll> // Ядро CLR
using namespace System;

class uClass; // Предварительное неполное объявление класса.
 class mClass; // Предварительное неполное объявление класса.

 #pragma managed
class mClass
 {
 public:
 uClass *ucP;  
mClass *mcP;  	
int x;

mClass()
   {
 // Только в неуправляемом коде!
 // cout << "Ha-Ha-Ha";

Console::WriteLine("mClass");
 // Легко посмотрели значение непроинициализированной переменной.
 Console::WriteLine(x.ToString());
 }
 ~mClass()
   {
 	  Console::WriteLine("~mClass");
   }

void mcF0()
 {
  Console::WriteLine("mcF0()");
 }

mClass* mcGenerator();

 };
 #pragma unmanaged

class uClass
 {
 public:
 uClass *ucP;  
mClass *mcP;  	
int x;
 	
uClass()
   {
    // Только в управляемом коде!
    //Console::WriteLine("Ha-Ha-Ha");
    printf("uClass\n");
   }
 ~uClass()
   {
    printf("~uClass\n");
   }

void ucF0()
 {
  cout << "ucF0()\n";
 }

uClass* ucGenerator();
 };
 // Судя по всему, функция Управляемого
 // класса может быть НеУправляемой!
 mClass* mClass::mcGenerator()
 {
  //x.ToString();
  //Console::WriteLine("Ha-Ha-Ha");
  cout << "Ha-Ha-Ha from unmanaged function of managed class!" << endl;
  ucP = new uClass();
  ucP->ucF0();
  delete ucP;
  return new mClass();
 }

 #pragma managed
 // А сделать Управляемой функцию НеУправляемого класса невозможно. 
 // Прагма managed для функции - члена неуправляемого класса игнорируется. 
uClass* uClass::ucGenerator()
 {
  cout << "Ha-Ha-Ha from function of unmanaged class!" << endl;
  //Console::WriteLine("Ha-Ha-Ha");
  //x.ToString();
  mcP = new mClass();
  mcP->mcF0();
  delete mcP;
  return new uClass();
 }
 #pragma unmanaged

int _tmain(int argc, _TCHAR* argv[])
 {
 void *xPoint;
 int x = 125;	

 // Только не смешивать!
 //Console::WriteLine("Ha-Ha-Ha");

mClass *mc = new mClass();
 mc->mcF0();
 xPoint = mc->mcGenerator();
 delete (mClass*)xPoint;
 delete mc;

uClass *uc = new uClass();
 uc->ucF0();
 xPoint = uc->ucGenerator();
 delete (uClass*)xPoint;
 delete uc;

return 0;
 }
Листинг 14.1.

Управляемая библиотека

Создание кода управляемой библиотеки тривиально. Для этого в Visual Studio предусмотрены специальные опции. Новый проект создается как библиотека классов (Class Library). Сборка автоматически получает расширение .dll.

C# основывается на парадигме объектно-ориентированного программирования, поэтому библиотека классов представляет собой все то же объявление класса.

Методы – члены класса составляют основу функциональности библиотеки. Наличие пары явно определяемых конструкторов – вынужденная мера. Это требование со стороны модуля на C++, использующего библиотеку. Там невозможно создать объект без явным образом объявленных конструкторов умолчания и копирования:

using System;

namespace CSLib00
 {
 public class Class1
 {
 // Явное объявление конструктора без параметров.
 public Class1()
 {
 }
         
 // Явное объявление конструктора копирования.
 // Конструктор с одним параметром – ссылкой на
 // объект - представитель собственного класса.
 // Именно такие конструкторы называются конструкторами
 // копирования.
 public Class1(Class1 cKey)
 {                
 }

 // Реализация функциональности. Метод - член класса Class1 Summ.
 public int Summ(int key1, int key2)
 {
 Console.WriteLine("this is Summ from CSLib00.dll");
 return (key1 + key2);        
 }
 }
 }
< Лекция 13 || Лекция 14: 12345 || Лекция 15 >
kewezok kewezok
kewezok kewezok
Елена Шляхт
Елена Шляхт
Объясните плиз в чем отличие а++ от ++а
Почему результат разный?
int a=0, b=0;
Console.WriteLine(a++); //0
Console.WriteLine(++b); //1
a++;
++b;
Console.WriteLine(a); //2
Console.WriteLine(b); //2