У Microsoft есть статья, посвященная работе с нативным кодов в .Net Core на различных платформах. Да, они приводят некоторые примеры, но О МНОГОМ не договаривают. Например, тут они вызывают функцию из WinAPI, чтобы вывести сообщение на экран А вот если dll-ка скомпилирована 32 битым компилятором, например стандартным из комплекта поставки Code::Blocks на Windows с MinGW32, то программа улетает с исключением BadImageFormatException Хотелось бы видеть ЖИВОЙ пример работы с нативным кодом на примере доступа к всплывающим уведомлениям на Ubuntu и Windows 10
Ссылку на скачивание ВСЕГО примера я оставил в самом низу ответа на вопрос
Linux
Тут всё просто, на 64 битной системе gcc по умолчанию будет компилировать 64 битные бинарники. Соответственно, задача сводится к написанию простейшей сишной функции, код снизу
#include <stdio.h>
#include <libnotify/notify.h>
int notify(const char *title, const char *description,int timeout)
{
notify_init("dcnn");
NotifyNotification* n = notify_notification_new (title, description, 0);
notify_notification_set_timeout(n, timeout);
if (!notify_notification_show(n, 0))
{
printf("Notification fallen");
return -1;
}
printf("Notificated");
//notify_uninit (void);
return 1;
}
Ничего сложного. Не вглядывайтесь в содержимое, это просто функция, которая может вернуть значение. main() кстати не нужен, так как далее мы вынесем её в .so, который сам по себе не будет запускаться. Компилируем через gcc со следующими параметрами:
gcc -Wall -shared -o native.so -fPIC native.c `pkg-config --cflags --libs gtk+-2.0 libnotify` -lnotify
Тут важно компилировать одной командой. Да, есть возможность сначала получить объектные модули .o, но компилятор при этом обязательно что нибудь забудет добавить... Рекомендую так же не отходя от кассы попытаться сделать динамичный импорт библиотеки из другой сишной программы, в репозитории в папке ubuntu лежит файл testing.c c её реализацией. Но если можете написать сразу правильно, то можно и пропустить
После сборки получаем файл native.so. Его нужно закинуть в папку со сборкой для .Net Core. По умолчанию у меня сборка появилась в директории
DotnetCoreNativeNotifications/bin/Debug/netcoreapp2.0/
Далее вызывается это дело просто. Всё как в документации MS
public class UbuntuNotify : AbstractNotify
{
public UbuntuNotify(){}
[DllImport("native.so")]
private static extern int notify([MarshalAs(UnmanagedType.LPStr)]string title,[MarshalAs(UnmanagedType.LPStr)]string description, int timeout);
public override void Notify(string title, string desc, int timeout)
{
UbuntuNotify.notify(title,desc,timeout);
}
}
В Program.cs я проверяю if-ом платформу, создаю экземпляр этого класса и вызываю метод Notify
Windows
Для начала выбираем правильное ПО для прикладного программирования. Не рекомендую пытаться написать dll в Visual Studio. На мой взгляд, она заточена ИМЕННО под C# и процесс написания динамически подключаемой библиотеки в ней затянется на долгое время, так как тупо нет шаблона проекта, собирающего dll
Берем Code::Blocks, http://www.codeblocks.org/
Далее ставим на него 64 битный компилятор. Это важно, без него .Net Core посчитает dll некоректной
Статья как поставить такой тут, https://medium.com/@yzhong.cs/code-blocks-compile-64-bit-under-windows-with-mingw-w64-79101f5bbc02
Создаем проект dll, язык C++
Не забудьте выбрать ПРАВИЛЬНЫЙ компилятор
Далее он сгенерирует достаточно читаемый код. Посмотреть код dll который выводит уведомления на Windows можно тут https://github.com/tripolskypetr/DotnetCoreNativeNotifications/blob/master/windows/native/main.cpp
После того, как закончили написание dll, так же кидаем его в папку со сборкой .Net Core, для обращения я реализовал следующий класс
public class WindowsNotify : AbstractNotify
{
public WindowsNotify(){}
[DllImport("native.dll", CallingConvention = CallingConvention.Cdecl)]
private extern static void NotifyFunc([MarshalAs(UnmanagedType.LPStr)]string title, [MarshalAs(UnmanagedType.LPStr)]string desc);
public override void Notify(string title, string desc, int timeout)
{
WindowsNotify.NotifyFunc(title,desc);
}
}
В итоге у нас получился проект .Net Core, который и на Ubuntu и на Windows 10 вывел нам уведомление. Чудеса
ВАЖНО: На разных версиях десятки может не работать, так как используется WinAPI и оно тоже меняется... Мой компьютер работает на версии 1703, она достаточно старая. Рекомендую попробовать тот же пример, но в dll на Windows вызывать функцию MessageBoxA как в шаблоне dll среды Code::Blocks, надеюсь мелкомягкие до неё не доберуться. Про linux я спокоен...
void DLL_EXPORT SomeFunction(const LPCSTR sometext)
{
MessageBoxA(0, sometext, "DLL Message", MB_OK | MB_ICONINFORMATION);
}
Посмотреть полный код данного примера можно тут, https://github.com/tripolskypetr/DotnetCoreNativeNotifications
Оборудование для ресторана: новинки профессиональной кухонной техники
Частный дом престарелых в Киеве: комфорт, забота и профессиональный уход
Друзья,вылетает программа после ввода поля tabl[i]name; Не могу понять в чём проблема
Помогите, пожалуйста, исправить код моей первой программыОна должна анализировать буфер обмена на наличие в нём 5-ти значного числа начинающегося...
Как создать AutoCompleteTextView внутри кастомного меню?