Совмещение управляемого и неуправляемого кодов
Управляемая библиотека в управляемом коде
Использование управляемой библиотеки в управляемом коде тривиально. Главная проблема, которая возникает при разработке приложения, использующего код управляемой библиотеки, – добавить ссылку (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, а также определение местоположения адреса функции в памяти, выполняется только при первом вызове функции.