Выбрать главу

Я бы в любой день взял прирост производительности в 2-3 раза.

Резюме

И вот оно: одновременная обработка нескольких входных файлов! Параллельное программирование может быть ценным инструментом для создания высокопроизводительных приложений, позволяя разбивать рабочие нагрузки, связанные с IO, так, чтобы некоторая часть работы выполнялась постоянно. Кроме того, его можно использовать для уменьшения объема памяти приложения за счет одновременной обработки входных данных по мере их поступления, без необходимости ждать и загружать все данные в память.

На данный момент наш CLI почти готов! Теперь он может эффективно обрабатывать как одиночные, так и множественные входные файлы. Он может передавать данные в потоковом режиме, чтобы уменьшить использование памяти, и настроен для простой поддержки использования библиотек. Далее мы собираемся сделать что-то немного другое: мы собираемся поддерживать отправку уведомлений на рабочем столе о различных событиях в нашем CLI. Для этого в следующей главе мы узнаем о способности Crystal связываться с библиотеками C.

7. Совместимость c C

В этой главе основное внимание будет уделено одной из наиболее продвинутых функций Crystaclass="underline" возможности взаимодействия с существующими библиотеками C путем написания привязок C. Эта функция Crystal позволяет повторно использовать высокооптимизированный и/или надежный код внутри Crystal, не написав ни строчки C и не беря на себя нетривиальную задачу по переносу всего этого в Crystal. Мы рассмотрим следующие темы:

• Знакомство с привязками C.

• Привязка libnotify

• Интеграция привязок

libnotify позволяет отправлять уведомления на рабочий стол в качестве средства предоставления пользователю ненавязчивой информации при возникновении событий. Мы собираемся использовать эту библиотеку для отправки собственных уведомлений.

К концу этой главы вы сможете писать привязки C для существующих библиотек и понимать, как лучше всего скрыть детали реализации привязок от конечного пользователя. Привязки C позволяют коду Crystal использовать высокооптимизированный код C или просто разрешать повторное использование кода без необходимости предварительного переноса всей библиотеки в Crystal.

Технические требования

Требования к этой главе следующие:

• Рабочая установка Кристалла.

• Рабочая установка jq.

• Рабочая установка libnotify.

• Рабочий компилятор C, например GCC.

Инструкции по настройке Crystal можно найти в Главе 1 «Введение в Crystal». Последние версии jq, libnotify и GCC, скорее всего, можно установить с помощью менеджера пакетов в вашей системе, но их также можно установить вручную, загрузив их с https://stedolan.github.io/jq/download, https://gitlab. gnome.org/GNOME/libnotify и https://gcc.gnu.org/releases.html соответственно. Если вы работаете с этой главой в ОС, отличной от Linux, например, macOS или Windows/WSL, то все может работать не так, как ожидалось, если вообще работать.

Все примеры кода, использованные в этой главе, можно найти в папке главы 7 на GitHub: https://github.com/PacktPublishing/Crystal-Programming/tree/main/Chapter07.

Вводим привязки на языке C

Написание привязок C предполагает использование некоторых конкретных ключевых слов и концепций Crystal для определения API библиотеки C, например, какие функции она имеет, каковы аргументы и какой тип возвращаемого значения. Затем Crystal может использовать эти определения, чтобы определить, как их использовать. Конечным результатом является возможность вызывать функции библиотеки C из Crystal без необходимости писать код C самостоятельно. Прежде чем мы углубимся непосредственно в привязку libnotify, давайте начнем с нескольких более простых примеров, чтобы представить концепции и тому подобное. Возьмем, к примеру, этот простой файл C:

#include <stdio.h>

void sayHello(const char *name)

{

    printf("Hello %s!\n", name);

}

Мы определяем одну функцию, которая принимает указатель char, представляющий имя человека, с которым можно поздороваться. Затем мы можем определить наши привязки:

@[Link(ldflags: "#{ DIR }/hello.o")]

lib LibHello

    fun say_hello = sayHello(name : LibC::Char*) : Void

end

LibHello.say_hello "Bob"