В Mono класс System.Console поддерживается не полностью, но Mono замечателен тем, что также как и в .NET можно использовать P/Invoke, для вызова методов нативных C/C++ Linux библиотек.
В моем случае это была библиотека ncurses. Выглядит это так:
public class Curses
{
/// <summary>
/// файл подключаемой библиотеки
/// </summary>
const string NCurses = "libncursesw.so.5";
/// <summary>
/// указатель на окно терминала
/// </summary>
private IntPtr window;
[DllImport(NCurses)]
private extern static IntPtr initscr();
/// <summary>
/// конструктор класса обертки
/// </summary>
public Curses()
{
window = initscr();
}
[DllImport(NCurses)]
private extern static int endwin();
/// <summary>
/// Деструктор обертки
/// </summary>
~Curses()
{
int result = endwin();
}
[DllImport(NCurses)]
private extern static int mvwprintw(IntPtr window, int y, int x, string message);
/// <summary>
/// Вывод сообщения по координатам
/// </summary>
public int Print(int x, int y, string message)
{
return mvwprintw(window, y, x, message);
}
[DllImport(NCurses)]
private extern static int refresh(IntPtr window);
/// <summary>
/// Обновление окна терминала
/// </summary>
public int Refresh()
{
return refresh(window);
}
. . .
Все методы ncurses в этом проекте подключались по мере необходимости, в случае если System.Console работал не должным образом, но если же стандартный метод работал это значительно облегчало жизнь.
Например метод ncurses wgetch() получает два байта вместо одного для символов Юникода, и для кириллической раскладки мне пришлось бы использовать более сложный метод с передачей указателя. Использование стандартного Console.ReadKey позволило оставить весь код управляемым и легко разделить функциональные клавиши от текстовых символов.
С чтением и записью файлов также не возникло проблем и все работало штатно как и на .NET
Когда уже все стабильно работало, была предпринята попытка собрать этот блокнот на Windows. Дабы не собирать PDCurses из исходников, я взял готовую dll из состава MinGW, а именно libpdcursesw.dll и она хорошо справилась в качестве замены ncurses.
Для сборки блокнота мне даже не понадобился Mono, я просто открыл решение MonoDevelop в Visual Studio без всяких приключений.
Единственное что потребовало корректировки, это вывод в консоль, мне пришлось отказаться от mvwprintw и я переписал Print, вывод заработал а изменения в коде были минимальны:
public void Print(int x, int y, string message)
{
Console.SetCursorPosition(x, y);
Console.Write(message);
}
Также пришлось подкорректировать размеры рабочей области, и методы изменения цвета текста.
Все это убедило меня в том, что C# вполне годится для задач под Linux и решения в случае чего легко портировать на Windows.
Полная реализация доступна на GitHub, ветка master для Linux и windows для Windows.
Комментарии (16)
Doomsday_nxt
25.09.2019 13:18+1А зачем в линуксе mono, когда есть dotnet core?
Qautomat Автор
25.09.2019 14:04единственный плюс, который приходит на ум, это GTK# и конструктор форм для него
… вспоминается еще MonoGame, но я про него ничего сказать не могу, кроме того что игровой движок, на котором сделано пара проектов
a-tk
26.09.2019 19:17+1Автор, у Вас точно C# привычный язык, а не С++?
Странно в коде видеть финализатор (который совсем не то же самое, что в С++ деструктор) и полностью проигнорированный IDisposable. Отсутствие инкапсуляции, каких-то более-менее пригодных к работе абстракций и т.п.
Ну да, в Mono тоже есть p/invoke. И это единственный посыл статьи?..Qautomat Автор
27.09.2019 14:49обертки сделаны по рекомендациям учебника по Mono, проект just4fun, что отражено в названии. Для реализации хватило стандартных типов. Наиболее полной реализацией ncurses считаю mono-curses от migueldeicaza
staticmain
А это какой-то встроенный тип документации? Выглядит максимально неоптимально и нечитаемо относительно Doxygen:
Qautomat Автор
summary отображается в IDE как всплывающая подсказка если навести курсор мыши на название
staticmain
Еще одна причина не использовать MonoDevelop. Это же максимально нечитаемо выглядит в коде.
Qautomat Автор
в Visual Studio оно так же работает, pastenow.ru/d2cf8ae9f6762fcf2f3710c965f7a747
можно не проваливаться в метод, а просто прочитать там где он вызывается
staticmain
Не, ну серьезно? Люди сейчас яростно с пихом в скор и карму доказывают, что XML-комментарии лучше, чем двусимвольная метка? Чисто потому, что MS решили создать очередной собственный велосипед?
Qautomat Автор
кто как привык, я привык к тем требованиям, которые на работе приняты
Doomsday_nxt
Кроме собственно описания элемента, xml-комментарии также могут содержать дополнительные сведения. Например, описания параметров метода, описания возвращаемого значения, ссылки на другие типы, ссылки на документацию. А еще из xml-комментариев генерируются файлы xml-документации которые кладутся рядом с библиотекой и при использовании библиотеки в другом проекте — вы получите нативные подсказки.
habr.com/ru/post/41514
staticmain
Ну то есть как doxygen, но не как doxygen, ибо NIH:
Doomsday_nxt
Честно, имхо, выглядит ужасно… Хотя, не спорю, возможно дело привычки…
Xandrmoro
Строго лучше, потому что зачем лезть чёрте-куда в исходники, которых может не быть, вместо того чтобы увидеть красивую всплывающую подсказку в автокомплите?