Различия между версиями 8 и 9
Версия 8 от 2020-11-29 17:02:12
Размер: 16071
Редактор: FrBrGeorge
Комментарий:
Версия 9 от 2020-11-29 17:02:55
Размер: 16075
Редактор: FrBrGeorge
Комментарий:
Удаления помечены так. Добавления помечены так.
Строка 294: Строка 294:
  * понятие «слова» — традиционное: есть символы-«буквы», из которых состоит слово и символы «разделители», последовальности которых стоят между словами. Классификация на ваше усмотрение, лишь бы в строке их находилось несколько и они были разной длины ☺   * понятие «слова» — традиционное: есть символы-«буквы», из которых состоит слово и символы «разделители», последовательности которых стоят между словами. Классификация на ваше усмотрение, лишь бы в строке их находилось несколько и они были разной длины ☺

Внешние библиотеки

Целевые библиотеки

Аксиома: всё уже написали до нас

  • ⇒ Сначала поиск, потом проектирование и исследование, потом разработка
  • Ресурсы:
    • GitHub: хостинг, аналитика, зеркалирование

    • OpenHub — аналитика

    • ресурсы сообществ (дистрибутивов, больших проектов и т. п.)
    • ЯП-специфичные хранилища (типа PyPI, NPM, Hackage и т. д.)
    • Гугл

Критерии качества:

  • Команда и сообщество
  • Возраст проекта
  • Регулярность разработки
  • Качество кода
  • Лицензия

Инструментарии (frameworks)

Цели инструментария:

  • Кроссплатформенность (возможно, прозрачная!)
  • Расширение и переписывание стандартов
  • Связное информационное пространство
  • Общая идеология разработки
  • Комфортная среда для DevOps

  • ⇒ привлечение сообщества

GLib/GObject

Glib (Си):

  • типы данных

    • Аналоги типов в Си (числа, ссылки, строки и т. п.)
      • в т. ч. надёжная арифметика, атомарные операции
    • Составные типы

      • Списки и двунаправленные списки
      • Стеки и очереди
      • Словари (ассоциативные массивы, хеш-таблицы)
      • Строки (человеческие ☺) и кварки (уникальные числовые хеши строк)

      • Динамические массивы, косвенные (массивы ссылок), байтовые и т. п.
      • Деревья (разные)
      • Вариатвные
    • Поддержка refcount
  • На все остальные случаи жизни:
    • i18n
    • память, куча, динамическая загрузка кода
    • процессы, нити, таймеры
    • лексический анализатор, синтаксические анализаторы…
    • I/O, потоки
    • Отладка и диагностика, модульное тестирование
  • Свои инструменты тестирования, интернационализации и т. п.
  • Требует жёсткой дисциплины программирования (все объекты кастятся в gpointer*, проверка типов только руками)

GObject (Си):

  • Поддержка ООП на Си
  • Классическая динамическая объектная модель
    • Классы и экземпляры
      • и для класса, и для экземпляра ∃ конструктор, инициализатор, финализатор и деструктор
    • Инкапсуляция, наследование, полиморфизм
    • Интроспекция и интерфейсы
  • Поддержка событийного программирования
    • Замыкания (более общий вид callbask-ов)
    • Сигналы
  • Всё программируется на Си с максимально возможной прослойкой макросов, генерирующих недостающие проверки, интерфейсы, структуры и прочее
    • Например, различаются наследуемые и ненаследуемые классы (если класс ненаследуемый, нет необходимости работать динамически с его структурой
  • Объектная модель очень гибкая, потому что каждый этап эксплуатации класса и его экземпляра надо программировать отдельно
  • Требует жёсткой дисциплины программирования

Пример использования GLib

Базовая статья: Manage C data using the GLib collections — учебник Тома Копланда.

Репозиторий с примером разработки простейшей программы с использованием GSList

Пример использования GObject

Базовая серия статей Поперечно-полосатое программирование (Хабр).

  • справочник

  • tutorial

  • методичка

  • ещё одна

  • Минимальный код (спасибо человеку-гипножабе за gist)

       1 #include <glib-object.h>
       2 
       3 // Структура, из которой делается класс
       4 typedef struct FooBarClass_ {
       5   GObjectClass parent_class;
       6 } FooBarClass;
       7 
       8 // Структура, из которой делается экземпляр
       9 typedef struct FooBar_ {
      10   GObject parent;
      11 } FooBar;
      12 
      13 // Макро, порождающий набор функций, описывающих класс
      14 // FooBar — тип объекта, foo_bar — префикс для этих функций
      15 // G_TYPE_OBJECT — родительский класс
      16 G_DEFINE_TYPE (FooBar, foo_bar, G_TYPE_OBJECT)
      17 
      18 // Инициализатор класса. Может ничего не делать, но должен быть.
      19 static void foo_bar_class_init (FooBarClass *self) { }
      20 
      21 // Инициализатор объекта. Тоже может ничего не делать.
      22 static void foo_bar_init (FooBar *self) { }
      23 
      24 int main() {
      25     // Создание самого класса с помощью сгенерированной функции
      26     GType theClass = foo_bar_get_type();
      27     // Создание экземпляра класса
      28     GObject *theObj = g_object_new(foo_bar_get_type(), NULL);
      29     // Создание второй ссылки на объект
      30     g_object_ref(theObj);
      31     // Удаление двух ссылок
      32     g_object_unref(theObj);
      33     g_object_unref(theObj);
      34     // Если раскомментировать ещё один unref, приедет assertion
      35     // Это значит, что до этого момента всё работало!
      36     //g_object_unref(theObj);
      37 }
    

Более сложный пример

  • Заголовочный файл cats.h:

       1 #ifndef _MYMODULE_CAT_H_
       2 #define _MYMODULE_CAT_H_
       3 #include <glib-object.h>
       4 
       5 // Приезжают вспомогательные макросы
       6 G_BEGIN_DECLS
       7 
       8 // Класс Cat будет прописан в пространстве имён (модуле) MYMODULE
       9 #define MYMODULE_TYPE_CAT cat_get_type()
      10 // Тип Cat, префикс cat, модуль MYMODULE, префикс для модуля CAT
      11 // Родительский класс — GObject
      12 // От FINAL класса нельзя наследоваться, это сильно упрощает реализацию
      13 G_DECLARE_FINAL_TYPE (Cat, cat, MYMODULE, CAT, GObject) 
      14 
      15 // struct _CatClass для FINAL_TYPE генерируется автоматически
      16 // Структура для экземпляра класса
      17 struct _Cat
      18 {
      19         GObject parent;             // Объект родительского класса
      20         gchar *Name;                // Поле
      21         void (*say_meow) (Cat*);    // Пола для метода
      22 };
      23 
      24 // Конструктор экземпляра
      25 Cat* cat_new();
      26 
      27 // Функция, которая будет работать методом
      28 void cat_say_meow(Cat* self);
      29 
      30 G_END_DECLS
      31 
      32 #endif /* _MYMODULE_CAT_H_ */
      33 
    
  • Реализация класса cats.c

       1 #include <stdio.h>
       2 #include <glib.h>
       3 #include <glib/gprintf.h>
       4 #include "cats.h"
       5 
       6 // Определение класса (порождение функций)
       7 G_DEFINE_TYPE (Cat, cat, G_TYPE_OBJECT)
       8 
       9 // Реализация метода
      10 void cat_say_meow(Cat* self)
      11 {
      12         g_printf("%s say: MEOW!\n", self->Name);
      13 }
      14 
      15 // Инициализатор класса (посмотрим, когда вызывается)
      16 static void cat_class_init(CatClass* self)
      17 {
      18         printf("Cats invented.\n");
      19 }
      20 
      21 // Инициализатор экземпляра (посмотрим, когда вызывается)
      22 static void cat_init(Cat* self)
      23 {
      24         printf("A cat was born.\n");
      25 }
      26 
      27 // Конструктор экземпляра
      28 Cat* cat_new(gchar *Name)
      29 {
      30         Cat* self;
      31 
      32         self = g_object_new(MYMODULE_TYPE_CAT, NULL);
      33         self->Name = Name;
      34         self->say_meow = cat_say_meow;
      35         return self;
      36 }
    
  • Использование класса, kitty.c

       1 #include "cats.h"
       2 #include "config.h"
       3 
       4 int main(int argc, char* argv[])
       5 {
       6         Cat* cat_a = cat_new("Kitty");
       7         Cat* cat_b = cat_new("Snowy");
       8         cat_say_meow(cat_a);
       9         cat_say_meow(cat_b);
      10         cat_say_meow(cat_a);
      11         return 0;
      12 }
    
  • Получим:
       1 $ cc cats.c kitty.c `pkg-config --cflags glib-2.0` -lgobject-2.0 -lglib-2.0 -o kitty
       2 $ ./kitty 
       3 Cats invented.
       4 A cat was born.
       5 A cat was born.
       6 Kitty say: MEOW!
       7 Snowy say: MEOW!
       8 Kitty say: MEOW!
       9 
    

Другие инструментарии

Универсальных для Си очень мало, и они маложивые

Для более высокоуровневых языков обкатывают на стророне, а потом забирают в базовый комплект библиотек (как в Python, JS и т. п.) или вообще в стандарт (как с C++)

Инструментарии C++

Boost

Цели:

  • Тестирование перед включением в стандарт C++
  • Best practices, которые не могут быть включены в стандарт (не кросс-платформенные, разрозненные, слишком привязанные к предметной области и т. п.)

Например (я не уверен, что часть этих тем уже не перекочевала в стандарт C++ ☺):

  • Алгоритмы
  • Поддержка разных компиляторов
  • Многопоточное программирование
  • Контейнеры
  • Модульное тестирование
  • Структуры данных
  • Функциональные объекты
  • Обобщённое программирование
  • Графы
  • Работа с геометрическими данными
  • Ввод/вывод
  • Межъязыковая поддержка
  • Итераторы
  • Математические и числовые алгоритмы
  • Работа с памятью
  • Синтаксический и лексический разбор
  • Метапрограммирование на основе препроцессора
  • Метапрограммирование на основе шаблонов
  • «Умные указатели»
  • Обработка строк и текста

Qt (сайт выглядит как извержение маркетоидного бреда, но на самом деле нет!)

Цели:

  • Ускорение/стандартизация разработки
  • Создание полного devops-окружения
  • Прозрачная кроссплатформенность на C++

Свойства:

  • Надстройка над C++

    • Мета-объекты
    • Динамическая объектная модель
    • Слоты/сигналы
  • Множество прикладных модулей

  • GUI, мультимедиа и GUI over мультимедиа ☺
  • Сеть и Web
  • Быстрая разработка приложений на декларативном языке Quick
  • БД
  • Тестирование

wxWidgets Типичный представитель кроссплатформенного GUI Toolkit, но:

  • Фишка: для бекенда исопльзуются нативные OS (для Linux — Gtk)

  • Есть б/м стандартный набор классов общего назначения wxBase

Д/З

  1. Почитать и по возможности отщёлкать Manage C data using the GLib collections — учебник Тома Копланда.

    • В любом случае разобраться с Hash Tables — задание про них)
  2. Написать программу, которая подсчитывает количество вхождений каждого слова из входного текста в этот самый текст, и выводит отсортированную по частоте статистику (второй ключ сортировки не важен)
    • Ширина строки текста — не более 80 символов
    • понятие «слова» — традиционное: есть символы-«буквы», из которых состоит слово и символы «разделители», последовательности которых стоят между словами. Классификация на ваше усмотрение, лишь бы в строке их находилось несколько и они были разной длины ☺
    • Использовать как минимум g_hash_table, но лучше ещё

      • g_strsplit()

      • сортировку (GSlist или GArray)
      • <!> и вообще обойтись без функций из libc

    • Как минимум сделать Make или ninja проект, но можно autotoos / cmake / …
  3. Выложить исходники результата в подкаталог 11_Toolkits отчётного репозитория

LecturesCMC/LinuxApplicationDevelopment2020/11_Toolkits (последним исправлял пользователь FrBrGeorge 2020-11-29 17:02:55)