Замыкания
Last updated
Was this helpful?
Last updated
Was this helpful?
Замыкания являются центром концепции асинхронных сигналов, которая широко используется повсюду в GTK+ и GNOME приложениях. Замыкание - основное представление callback-функций. Это небольшая структура содержащая дерево объектов:
указатель функции (непосредственно сама callback-функция), чей прототип похож на:
Указатель user_data который помещается в callback-функцию при вызове замыкания
указатель функции который представляет деструктор замыкания: всякий раз когда количество ссылок замыкания достигает нуля, эта функция вызывается перед освобождением сструктуры замыкания.
Структура представляет основную функциональность всех замкнутых реализаций: существуют разные реализации Замыканий для каждого отдельного рабочего цикла который хочет использовать систему типов GObject. [] Библиотека GObject обеспечивает простой тип который является определением реализации замыканий используемый с C/C++ callback-функциями.
представляет простые сервисы:
Вызов (): это то, для чего были созданы замыкания: они скрывают детали callback-вызовов из callback-вызовов.
Уведомление: замыкания уведомляют об определённых событиях, таких как запрос замыкания, аннулирование замыкания и финализация замыкания. Ожидающие сообщений могут быть зарегистрированы с помощью (уведомление финализации), (уведомление аннулирования) и (уведемление запроса). Существуют симметричные нерегистрационные функции для событий финализации и аннулирования ( и ) но не для выполнения запроса. []
Если вы используете C или C++ для подключения callback-функции к данному событию, то вы будете использовать либо просто которая имеет довольно минимальный API, или ещё более простые функции (которые будут продемонстрированы немного позже :).
Как объяснялось выше, Замыкания скрывают подробности callback-вызовов. В C, callback-вызов такой же вызов функции: это просто вопрос создания правильного стека для вызова функции и выполнения трансляции команды вызова.
'C' маршаллеры замыканий преобразуют массив GValues, который представляет параметры целевой функции, в список параметров функций в C-стиле, вызывая предоставленную пользователем C функцию с этим списком параметров, получают возвращаемое значение функции, преобразуют его в GValue и возвращают это GValue в вызывающую программу.
Следующий код реализует простой маршаллер в C для C функции которая принимает целочисленное как первый параметр и ничего не возвращает.
Конечно, существуют другие виды маршаллеров. Например, James Henstridge написал родной для Python маршаллер который используется всеми замыканиями языка python (замыкания python используются python-based callback-функциями вызываемыми процессом запрса замыкания). Этот python маршаллер преобразует введённый список GValue представляющий параметры функции в эквивалентную структурную запись Python (вы можете посмотреть pyg_closure_marshal
вpygtype.c
в модуле pygobject GNOME cvs server).
создаёт новое замыкание которое может вызвать обеспеченную пользователем callback_func с обеспеченным пользователем user_data в качестве последнего параметра. Когда замыкание финализируется (второй этап процесса уничтожения), оно вызовет функцию destroy_data если пользователь её предоставил.
создаёт новое замыкание которое может вызвать обеспеченную пользователем callback_func с обеспеченным пользователем user_data в качестве первого параметра (а не последнего параметра как в ). Когда замыкание финализируется (второй этап процесса уничтожения), оно вызовет функцию destroy_data если пользователь её предоставил.
[] На практике, Замыкания находятся в границах языкового окружения: если вы пишите код на python и один из ваших Python callback-вызовов получает сигнал одного из виджетов GTK+, код на C в GTK+ должен выполнить ваш код на Python. Замыкание вызывающее GTK+ object вызывает Python callback-вызов: он ведёт себя как обычный C object для GTK+ и как обычный Python object для python кода.
[] Замыкания подсчитывают ссылки и уведомляют слушателя относительно своего уничтожения в два этапа: уведомление аннулирования вызывается перед уведомлением финализации.