Совмещение управляемого и неуправляемого кодов
Управляемая библиотека в управляемом коде
Использование управляемой библиотеки в управляемом коде тривиально. Главная проблема, которая возникает при разработке приложения, использующего код управляемой библиотеки, – добавить ссылку (Add Reference) на библиотечную сборку. Для этого нужно указать месторасположение сборки в соответствующем диалоговом окне.
После этого Visual Studio копирует сборку в директорию, в которой располагается разрабатываемый код. При согласовании пространств имен (оператор using или использование полного имени с точечной нотацией) библиотечного модуля и модуля клиента, библиотечные классы и методы готовы к использованию в коде клиента:
using System;
namespace CSClient
{
class Program
{
static void Main(string[] args)
{
// Здесь используется точечная нотация.
// Явное указание принадлежности имени класса
// пространству имен CSLib00.
CSLib00.Class1 c1 = new CSLib00.Class1();
// Создали объект, затем вызываем метод!
Console.WriteLine("the res = {0}", c1.Summ(1, 2));
}
}
}Управляемая библиотека в неуправляемом коде
Особенности разработки неуправляемого программного кода, использующего управляемую библиотеку, состоят в следующем:
- неуправляемый код транслируется с опцией /clr;
- добавляется ссылка на библиотечную сборку;
- определяется управляемая функция, в теле которой с помощью оператора gcnew создается объект объявленного в управляемой библиотеке класса, от имени которого вызывается библиотечная функция.
#include "stdafx.h"
#using <mscorlib.dll>
using namespace System;
using namespace CSLib00;
#pragma managed
void managedLibStarter()
{
Class1 cl1 = gcnew Class1();
Console::WriteLine("{0}",cl1.Summ(1,2));
}
#pragma unmanaged
int _tmain(int argc, _TCHAR* argv[])
{
printf("QWERTY\n");
managedLibStarter();
return 0;
}Вызов неуправляемых функций из управляемого модуля
Платформный вызов — это служба, которая позволяет управляемому программному коду вызывать неуправляемые функции, реализованные в библиотеках динамической компоновки (DLL), например, функции библиотек Win32 API.
Служба платформного вызова обеспечивает поиск и вызов экспортируемой функции и в случае необходимости обеспечивает маршалинг ее параметров (передачу параметров через границы процесса).
Платформный вызов позволяет управлять значительной частью операционной системы посредством вызова функций Win32 API и других библиотек DLL. В дополнение к Win32 API, через платформный вызов доступны многие другие интерфейсы API и DLL.
Вызов неуправляемых функций средствами платформного вызова предполагает следующие действия:
- идентификация вызываемой функции в библиотеке DLL;
- создание класса для сохранения вызываемой функции;
- объявление прототипа (!) вызываемой функции в управляемом коде;
- вызов функции.
При вызове неуправляемой функции платформный вызов выполняет следующую последовательность действий:
- определяется местонахождение DLL-библиотеки, содержащей функцию;
- DLL загружается в память;
- определяется месторасположение вызываемой функции (адрес функции в памяти);
- значения параметров функции заносятся в стек;
- в случае необходимости осуществляется маршалинг данных;
- осуществляется передача управления неуправляемой функции.
В лучших традициях .NET определение местонахождения и загрузка DLL, а также определение местоположения адреса функции в памяти, выполняется только при первом вызове функции.