3. Первопричина исследования
Многие вещи легко делаются с использованием
.NET
Однако, старые большие проекты проще оставить
на С++ и не пытаться переделывать ради простоты
пары функций
Но COM взаимодействие – это просто слёзы, так
как же этими функциями воспользоваться?
4. Хороший пример от Microsoft
MSDN содержит целых два примера по вызову
форм и элементов форм Winforms из MFC
https://msdn.microsoft.com/ru-ru/library/ahdd1h97.aspx
#pragma managed
#pragma unmanaged
#pragma managed([push,] on | off)
#pragma managed(pop)
7. Что имеем
Никакой защиты, код легко вскрывается
CLR код не поддерживает множественного
наследования
Однако, приложенный в MSDN пример не имеет
подобных проблем!
В тексте, поясняющем технологию, об этом ни
слова
Но детальный анализ исходного кода выявил
причину
11. Вызов Windows Forms из MFC
Управляемой или неуправляемой может быть
функция, обрамляем именно её
Управляемые переменные могут располагаться
только в управляемых функциях
Машинные – в любых
Вместо new используем gcnew
Вместо * указатели обозначаем ^
13. Результат
Для старых проектов, новые функции могут
разрабатываться .NET программистами без
изменения основного кода
При этом, никто не мешает старой команде
продолжать работать в старой среде, так как
перескоки из одного вида кода в другой могут
происходить многократно
14. Не все переменные из машинного кода могут свободно
существовать в управляемой среде и наоборот
15. Два правила преобразования
Многие источники посвящают километровые
статьи правилам преобразования, но всё намного
проще:
Скалярные переменные преобразуются
автоматически
Для остальных добавляем:
using namespace System::Runtime::InteropServices;
и оттуда используем класс Marshal, наверняка всё
нужное там уже есть
16. ANSI строки к управляемым
System::String^ Text =
Marshal::PtrToStringAnsi((System::IntPtr)(void*)txt);
18. Массивы
Вот так описывается управляемый массив аналог
шарпового WORD[] Info:
array<WORD>^ Info;
99% авторов преобразуют массивы поэлементно
На самом деле, управляемый массив очень похож
на обычный, просто у него есть заголовок, плюс
его в любой момент может перенести сборщик
мусора
Чтобы отключить работу сборщика мусора для
массива, используем:
pin_ptr <WORD> pp = &Info[0];
m_jtag->SaveParallelFlash (hFile,(WORD*)pp);
24. .NET плагины
Делаем .NET интерфейс из своей программы
наружу
Кроме того, добавляем штатную
функциональность поиска плагинов,
реализованную в .NET
Получаем возможность расширения
функциональности без выдачи исходных текстов
сторонним разработчикам
Ну, и возможность расширения функций
группами .NET программистов
25. Нижний уровень .NET
приложений
Классический подход для вызова нижнего уровня
из .NET приложений – разработка DLL
Но можно сделать смешанный код, содержащий
переход от одного к другому через #pragma
Примеры: Работа с JTAG адаптером или с
жёстикими дисками + .NET класс,
обеспечивающий стыковку с обычным .NET кодом
26. «Оборачивание» Си-кода
Иногда есть старые, но сложные библиотеки,
написанные на С++ или даже Си. Пример – парсер
BSDL кода. И программа и структуры данных –
сишные. Переписывать – долго
Делаем смешанный код, содержащий .NET
прослойку, обеспечивающую вызов старого кода и
преобразование данных. Трудозатраты – 1
человеко-день.
27.
28. Смешивание кода:
Упрощает вызовы .NET библиотек, охватывающих
широкий набор функций
Позволяет работать над старым проектом .NET
разработчиков (можно – параллельно с
разработчиками на классическом С++)
Позволяет добавлять .NET разработчиков без
передачи им исходных кодов
Позволяет делать «прозрачный» стык
классической реализации «нижнего» и .NET
реализации «верхнего» уровней