Владислав Шаклеин. Смешивание управляемого и...
-
Upload
platonov-sergey -
Category
Software
-
view
346 -
download
4
Transcript of Владислав Шаклеин. Смешивание управляемого и...
примеры практического использования
Причины, подтолкнувшие к поиску решения и основные методы для смешивания кода
Первопричина исследованияМногие вещи легко делаются с
использованием .NETОднако, старые большие проекты проще
оставить на С++ и не пытаться переделывать ради простоты пары функций
Но COM взаимодействие – это просто слёзы, так как же этими функциями воспользоваться?
Хороший пример от MicrosoftMSDN содержит целых два примера по
вызову форм и элементов форм Winforms из MFC
https://msdn.microsoft.com/ru-ru/library/ahdd1h97.aspx
#pragma managed#pragma unmanaged#pragma managed([push,] on | off)#pragma managed(pop)
Ключевые моменты примеров
Однако, получаем трудность
Что имеемНикакой защиты, код легко вскрываетсяCLR код не поддерживает множественного
наследования
Однако, приложенный в MSDN пример не имеет подобных проблем!
В тексте, поясняющем технологию, об этом ни слова
Но детальный анализ исходного кода выявил причину
Кто ищет, тот всегда найдёт
В результате, получаем
Просто вызов управляемого кода из машинного (и наоборот)
Вызов Windows Forms из MFCУправляемой или неуправляемой может
быть функция, обрамляем именно еёУправляемые переменные могут
располагаться только в управляемых функциях
Машинные – в любыхВместо new используем gcnewВместо * указатели обозначаем ^
Пример
РезультатДля старых проектов, новые функции
могут разрабатываться .NET программистами без изменения основного кода
При этом, никто не мешает старой команде продолжать работать в старой среде, так как перескоки из одного вида кода в другой могут происходить многократно
Не все переменные из машинного кода могут свободно существовать в управляемой среде и наоборот
Два правила преобразованияМногие источники посвящают
километровые статьи правилам преобразования, но всё намного проще:
Скалярные переменные преобразуются автоматически
Для остальных добавляем:using namespace System::Runtime::InteropServices;и оттуда используем класс Marshal, наверняка всё нужное там уже есть
ANSI строки к управляемымSystem::String^ Text =
Marshal::PtrToStringAnsi((System::IntPtr)(void*)txt);
Управляемые к ANSIchar* ptr = (char*)(void*)
Marshal::StringToHGlobalAnsi (subItem->Text);
…
Marshal::FreeHGlobal ((System::IntPtr)(void*)ptr);
МассивыВот так описывается управляемый массив
аналог шарпового WORD[] Info:array<WORD>^ Info;
99% авторов преобразуют массивы поэлементноНа самом деле, управляемый массив очень
похож на обычный, просто у него есть заголовок, плюс его в любой момент может перенести сборщик мусора
Чтобы отключить работу сборщика мусора для массива, используем:pin_ptr <WORD> pp = &Info[0];m_jtag->SaveParallelFlash (hFile,(WORD*)pp);
Собственно, то, ради чего и задумывались все исследования
Главное – добавить ссылку
Помним, что…Управляемые стековые переменные можно
заводить только в управляемом кодеОбычные – в любом
Наброски примера
Что ещё можно «выжать» из смешивания кода
.NET плагиныДелаем .NET интерфейс из своей программы
наружуКроме того, добавляем штатную
функциональность поиска плагинов, реализованную в .NET
Получаем возможность расширения функциональности без выдачи исходных текстов сторонним разработчикам
Ну, и возможность расширения функций группами .NET программистов
Нижний уровень .NET приложенийКлассический подход для вызова нижнего
уровня из .NET приложений – разработка DLL
Но можно сделать смешанный код, содержащий переход от одного к другому через #pragma
Примеры: Работа с JTAG адаптером или с жёстикими дисками + .NET класс, обеспечивающий стыковку с обычным .NET кодом
«Оборачивание» Си-кодаИногда есть старые, но сложные
библиотеки, написанные на С++ или даже Си. Пример – парсер BSDL кода. И программа и структуры данных – сишные. Переписывать – долго
Делаем смешанный код, содержащий .NET прослойку, обеспечивающую вызов старого кода и преобразование данных. Трудозатраты – 1 человеко-день.
Смешивание кода:Упрощает вызовы .NET библиотек,
охватывающих широкий набор функцийПозволяет работать над старым
проектом .NET разработчиков (можно – параллельно с разработчиками на классическом С++)
Позволяет добавлять .NET разработчиков без передачи им исходных кодов
Позволяет делать «прозрачный» стык классической реализации «нижнего» и .NET реализации «верхнего» уровней