GObject - GObject
Разработчики) | Проект GNOME |
---|---|
изначальный выпуск | 11 марта 2002 г. |
Стабильный выпуск | 2.64.4 (2 июля 2020 г.[±][1] | )
Написано в | C |
Операционная система | Кроссплатформенность |
Доступно в | Многоязычный[который? ] |
Тип | Программная библиотека |
Лицензия | GNU LGPL |
Интернет сайт | разработчик |
В Система объектов GLib, или же GObject, это свободный библиотека программного обеспечения предоставление портативного объектная система и прозрачная межъязыковая совместимость. GObject предназначен для использования как непосредственно в C программы для предоставления объектно-ориентированных API на основе C и через привязки на другие языки, чтобы обеспечить прозрачную межъязыковую совместимость, например PyGObject.
GObject Introspection
- GObject самоанализ (сокращенно GIR[2]) - это промежуточный уровень между библиотеками C (с использованием GObject) и языковыми привязками, см. Список языковых привязок для GTK.
История
В зависимости только от GLib и libc, GObject является краеугольным камнем ГНОМ и используется повсюду GTK, Панго, АТК, и на самом высоком уровне ГНОМ библиотеки вроде GStreamer и приложения. До GTK + 2.0 код, аналогичный GObject, был частью кодовой базы GTK. (Имя «GObject» еще не использовалось - общий базовый класс назывался GtkObject
.)
В выпуске GTK + 2.0 объектная система была выделена в отдельную библиотеку из-за ее общей полезности. При этом большинство не-GUI -конкретные части GtkObject
класс были переведены в GObject
, новый общий базовый класс. Библиотека GObject, существующая как отдельная библиотека с 11 марта 2002 г. (дата выпуска GTK + 2.0), теперь используется многими программами без графического интерфейса пользователя, такими как командная строка и сервер Приложения.
Отношение к GLib
Хотя у GObject есть свой отдельный набор документации[3] и обычно компилируется в собственный общая библиотека файл, исходный код GObject находится в GLib дерево исходных текстов и распространяется вместе с GLib. По этой причине GObject использует номера версий GLib и обычно упаковывается вместе с GLib (например, Debian помещает GObject в свой libglib2.0
семейство пакетов).
Система типов
На самом базовом уровне структуры GObject лежит общий и динамический система типов называется GType. Система GType содержит описание всех объектов, позволяющих клей код для облегчения привязки нескольких языков. Система типов может обрабатывать любые единолично унаследованный структура классов, в дополнение к неклассифицированный такие типы как непрозрачные указатели, струны, и разного размера целые числа и числа с плавающей запятой.
Система типов знает, как копировать, присваивать и уничтожать значения, принадлежащие любому из зарегистрированных типов. Это тривиально для таких типов, как целые числа, но многие сложные объекты подсчитанный по ссылкам, в то время как некоторые из них сложны, но не учитывают количество ссылок. Когда система типов «копирует» объект с подсчетом ссылок, она обычно просто увеличивает счетчик ссылок, тогда как при копировании сложного объекта без подсчета ссылок (например, строки) она обычно создает фактическую копию с помощью распределение памяти.
Эта базовая функциональность используется для реализации GValue
, тип универсального контейнера, который может содержать значения любого типа, известного системе типов. Такие контейнеры особенно полезны при взаимодействии с динамически типизированными языковыми средами, в которых все собственные значения находятся в таких помеченный типом контейнеры.
Основные типы
Типы, которые не связаны классы называются неклассифицированный. Эти типы вместе со всеми типами, соответствующими той или иной форме корневой класс, известны как основные типы: типы, от которых происходят все остальные типы. Они составляют относительно замкнутый набор, но хотя от обычного пользователя не ожидается, что он создаст свои собственные основные типы, возможность существует и использовалась для создания собственных иерархии классов - т.е. иерархии классов, не основанные на GObject
учебный класс.
Начиная с GLib 2.9.2,[4] то неклассифицированный встроенные основные типы:
- пустой тип, соответствующий C
пустота
(G_TYPE_NONE
); - типы, соответствующие C со знаком и без знака
char
,int
,длинная
, и 64-битные целые числа (G_TYPE_CHAR
,G_TYPE_UCHAR
,G_TYPE_INT
,G_TYPE_UINT
,G_TYPE_LONG
,G_TYPE_ULONG
,G_TYPE_INT64
, иG_TYPE_UINT64
); - логический тип (
G_TYPE_BOOLEAN
); - тип перечисления и тип «флаги», оба соответствующие C
перечислить
типа, но отличается тем, что последний используется только для битовые поля (G_TYPE_ENUM
иG_TYPE_FLAGS
); - типы для одинарной и двойной точности IEEE плавает, соответствующие C
плавать
идвойной
(G_TYPE_FLOAT
иG_TYPE_DOUBLE
); - строковый тип, соответствующий C
символ *
(G_TYPE_STRING
); - непрозрачный тип указателя, соответствующий C
пустота *
(G_TYPE_POINTER
).
В классифицированный встроенные основные типы:
- тип базового класса для экземпляров
GObject
, корень стандартного дерева наследования классов (G_TYPE_OBJECT
) - базовый тип интерфейса, аналогичный типу базового класса, но представляющий корень стандарта интерфейс дерево наследования (
G_TYPE_INTERFACE
) - тип для в штучной упаковке структуры, которые используются для обертывания простых объектов значений или посторонних объектов в «ящики» со счетчиком ссылок (
G_TYPE_BOXED
) - тип для «объектов спецификации параметров», которые используются в GObject для описания метаданные для свойств объекта (
G_TYPE_PARAM
).
Типы, которые могут быть созданы автоматически системой типов, называются инстанцируемый. Важной характеристикой этих типов является то, что первые байты любого экземпляра всегда содержат указатель на структура класса (форма виртуальный стол ) связанный с типом экземпляра. По этой причине любой экземплярный тип должен быть классифицирован. Напротив, любой неклассифицированный тип (например, целое число или нить) не должно быть инстанцируемым. С другой стороны, большинство классифицированных типов могут создавать экземпляры, но некоторые, например типы интерфейсов, нет.
Производные типы
Типы, производные от встроенных фундаментальных типов GObject, можно разделить на четыре категории:
- Нумерованные типы и типы «флаги»
- В общем, каждый перечислимый тип и каждый тип битового поля на основе целых чисел (т. Е. Каждый
перечислить
type), который желают использовать каким-либо образом, связанным с системой объектов - например, как тип свойства объекта - должен быть зарегистрирован в системе типов. Обычно код инициализации, который заботится о регистрации этих типов, генерируется автоматическим инструментом, называемымglib-mkenums
[5] и хранится в отдельном файле. - Типы в штучной упаковке
- Некоторые структуры данных, которые слишком просты для того, чтобы их можно было сделать полноценными типами классов (со всеми возникающими накладными расходами), возможно, все же потребуется зарегистрировать в системе типов. Например, у нас может быть класс, к которому мы хотим добавить
фоновый цвет
свойство, значения которого должны быть экземплярами структуры, которая выглядит какструктура цвет { int р, грамм, б; }
. Чтобы избежать подклассаGObject
, мы можем создать коробочный тип для представления этой структуры и предоставления функций для копирования и освобождения. GObject поставляется с несколькими упакованными типами, обертывающими простые типы данных GLib. Другое использование упакованных типов - это способ обернуть посторонние объекты в помеченный контейнер, который система типов может идентифицировать и будет знать, как копировать и освобождать. - Типы непрозрачных указателей
- Иногда для объектов, которые не нужно ни копировать, ни подсчитывать ссылки, ни освобождать, даже упакованный тип будет перебор. Хотя такие объекты можно использовать в GObject, просто рассматривая их как непрозрачные указатели (
G_TYPE_POINTER
), часто бывает хорошей идеей создать производный тип указателя, документируя тот факт, что указатели должны ссылаться на конкретный вид объекта, даже если об этом больше ничего не говорится. - Типы классов и интерфейсов
- Большинство типов в приложении GObject будут классами - в обычном объектно-ориентированном смысле слова - производными прямо или косвенно от корневого класса,
GObject
. Также есть интерфейсы, которые в отличие от классических Ява -стилевые интерфейсы, могут содержать реализованные методы. Таким образом, интерфейсы GObject можно описать как миксины.
Система обмена сообщениями
Система обмена сообщениями GObject состоит из двух взаимодополняющих частей: закрытие и сигналы.
- Закрытие
- Замыкание GObject - это обобщенная версия Перезвони. Существует поддержка замыканий, написанных на C и C ++, а также на произвольных языках (при наличии привязок). Это позволяет запускать код, написанный (например) на Python и Java через замыкание GObject.
- Сигналы
- Сигналы - это основной механизм, с помощью которого вызываются закрытия. Объекты регистрируют слушателей сигналов с помощью системы типов, определяя отображение между заданным сигналом и заданным замыканием. При выдаче зарегистрированного сигнала происходит закрытие этого сигнала. В GTK все собственные события графического интерфейса (такие как движение мыши и действия клавиатуры) могут генерировать сигналы GObject для слушателей, которые потенциально могут действовать.
Реализация класса
Каждый класс GObject реализуется как минимум двумя структурами: структура класса и структура экземпляра.
- Структура класса
- Структура классов соответствует vtable класса C ++. Он должен начинаться со структуры классов суперкласса. После этого он будет содержать набор указателей на функции - по одному для каждого виртуальный метод класса. Переменные, зависящие от класса, можно использовать для имитации членов класса.
- Структура экземпляра
- Структура экземпляра, которая будет существовать в одной копии для каждого экземпляра объекта, должна начинаться с структуры экземпляра объекта суперкласс (это гарантирует, что все экземпляры начинаются с указателя на структуру класса, поскольку все фундаментальные экземпляры типов разделяют это свойство). После данных, принадлежащих суперклассу, структура может содержать любые переменные, зависящие от экземпляра, соответствующие переменным-членам C ++.
Определение класса в структуре GObject - сложная задача, требующая большого количества шаблон код, такой как ручные определения макросов приведения типов и неясные заклинания регистрации типов. Кроме того, поскольку структура C не может иметь модификаторы доступа, такие как «общедоступный», «защищенный» или «частный», необходимо использовать обходные пути для предоставления инкапсуляция. Один из подходов - включить указатель на личные данные, которые обычно называются _priv
- в структуре экземпляра. В частная структура могут быть объявлены в общедоступном файле заголовка, но определены только в файле реализации, в результате чего личные данные будут непрозрачными для пользователей, но прозрачными для разработчика. Если частная структура зарегистрирована в GType, она будет автоматически выделена объектной системой. Действительно, даже не обязательно включать _priv
указатель, если кто-то хочет использовать заклинание G_TYPE_INSTANCE_GET_PRIVATE
каждый раз, когда требуются личные данные.
Для решения некоторых из этих сложностей существует несколько языков более высокого уровня, которые компиляция из исходного кода в исходный в GObject в C. Язык программирования Вала использует C # -style и предварительно обрабатывается в ваниль Код C. GObject Builder или GOB2, предлагает синтаксис шаблона, напоминающий Ява.
Применение
Комбинация C и GObject используется во многих успешных бесплатно программное обеспечение проекты, такие как ГНОМ рабочий стол, GTK инструментарий и GIMP программа для обработки изображений.
Хотя многие приложения GObject полностью написаны на C, система GObject хорошо согласуется с собственными объектными системами многих других языков, например C ++, Ява, Рубин, Python, Common Lisp, и .СЕТЬ /Мононуклеоз. В результате обычно относительно безболезненно создавать языковые привязки для хорошо написанных библиотек, использующих инфраструктуру GObject.
Однако написание кода GObject на C в первую очередь относительно многословно. Библиотека требует много времени для изучения, и программисты с опытом высокий уровень объектно-ориентированные языки часто находят несколько утомительным работать с GObject в C.Например, создание подкласса (даже просто подкласса GObject
) может потребоваться написание и / или копирование большого количества шаблонный код.[6] Однако, используя Вала, язык, который предназначен в первую очередь для работы с GObject и который конвертируется в C, вероятно, облегчит работу с GObject или написание библиотек на основе GObject.
Хотя они не совсем первоклассные объекты (в GType нет реальных метатипов), метаобъекты подобные классы и интерфейсы создаются приложениями GObject во время выполнения и обеспечивают хорошую поддержку самоанализ. Интроспективные возможности используются языковыми привязками и приложениями для разработки пользовательского интерфейса, такими как Поляна чтобы позволить делать такие вещи, как загрузка общая библиотека который предоставляет класс GObject - обычно какой-то виджет в случае Glade - а затем получить список всех свойств класса с информацией о типе и строками документации.
Сравнение с другими объектными системами
Эта секция возможно содержит оригинальные исследования.Декабрь 2011 г.) (Узнайте, как и когда удалить этот шаблон сообщения) ( |
Поскольку GObject предоставляет в основном полную объектную систему для C[нужна цитата ], его можно рассматривать как альтернативу языкам, производным от C, таким как C ++ и Цель-C. (Хотя оба они также предлагают множество других функций, помимо соответствующих объектных систем.) Легко наблюдаемая разница между C ++ и GObject заключается в том, что GObject (например, Java) не поддерживает множественное наследование.[7]
GObject использует GLib Функция выделения памяти g_malloc () заставит программу безоговорочно завершить работу при исчерпании памяти, в отличие от библиотеки C маллок (), C ++ новый и другие распространенные распределители памяти, которые позволяют программе справляться с ситуациями нехватки памяти или даже полностью восстанавливаться из них без простого сбоя.[8] Это, как правило, работает против включения GObject в программное обеспечение, где важна устойчивость перед лицом ограниченной памяти или где обычно обрабатывается очень много или очень большие объекты. G_try_new () можно использовать, когда с большей вероятностью произойдет сбой выделения памяти (например, для большого объекта), но это не может гарантировать, что выделение не завершится сбоем в другом месте кода.[9]
Еще одно важное отличие состоит в том, что, хотя C ++ и Objective-C являются отдельными языками, GObject является строго библиотекой и поэтому не вводит новый синтаксис или интеллект компилятора. Например, при написании кода C на основе GObject часто необходимо выполнить явное восходящий.[нужна цитата ] Следовательно, «C с GObject», рассматриваемый как язык, отдельный от простого C, является строгим надмножеством простого C - как Objective C, но в отличие от C ++.
На платформах, где нет стандарта ABI который работает во всех компиляторах C ++ (что обычно не так, поскольку обычно используются либо Itanium ABI, либо Microsoft ABI), библиотека, скомпилированная с помощью одного компилятора C ++, не всегда может вызвать библиотеку, скомпилированную с помощью другого компилятора.[нужна цитата ] Если такая совместимость требуется, методы C ++ должны быть экспортированы как простые функции C, что частично противоречит цели объектной системы C ++.[нужна цитата ] Проблема частично возникает из-за того, что разные компиляторы C ++ используют разные типы искажение имени для обеспечения уникальности всех экспортируемых символов. (Это необходимо, потому что, например, два разных класса могут иметь функции-члены с одинаковыми именами, одно имя функции может быть перегружен несколько раз, или функции с одинаковыми именами могут появляться в разных пространства имен, но в объектный код эти перекрытия не допускаются.)[нужна цитата ] Напротив, поскольку C не поддерживает какие-либо формы перегрузки или размещения имен, авторы библиотек C обычно используют явные префиксы, чтобы гарантировать глобальную уникальность своих экспортируемых имен.[нужна цитата ] Следовательно, несмотря на то, что она объектно-ориентированная, библиотека на основе GObject, написанная на C, всегда будет использовать одни и те же имена внешних символов независимо от того, какой компилятор используется.
Возможно, наиболее существенное различие заключается в акценте GObject на сигналах (называемых События на других языках).[нужна цитата ] Этот акцент проистекает из того факта, что GObject был специально разработан для удовлетворения потребностей инструментария GUI. Хотя существуют библиотеки сигналов для большинства объектно-ориентированных языков, в случае GObject они встроены в объектную систему. Из-за этого типичное приложение GObject будет иметь тенденцию использовать сигналы в гораздо большей степени, чем приложение, отличное от GObject, что делает GObject составные части гораздо больше инкапсулированный и многоразового использования, чем те, которые используют простой C ++ или Java.[нужна цитата ][согласно кому? ] При использовании glibmm /gtkmm, официальные оболочки C ++ для Glib / GTK соответственно, родственный проект libsigc ++ позволяет легко использовать базовые сигналы GObject с помощью стандартного C ++. Конечно, другие реализации сигналов доступны почти на всех платформах, хотя иногда требуется дополнительная библиотека, например Boost.Signals2 для C ++.
Смотрите также
- Вала - язык программирования на основе GObject с C # синтаксис. Исходный код в исходный компилятор к C.
- Джинн - альтернативный синтаксический анализатор для Python -стайл компилятор Vala
Рекомендации
- ^ Витналл, Филип (2 июля 2020 г.). "glib 2.64.4". Ftp-релиз GNOME (Список рассылки). Получено 14 августа 2020.
- ^ «Самоанализ, резюме». Разработчик Gnome, Руководство по программированию - Конкретные инструкции. Получено 9 августа 2020.
- ^ "Справочное руководство GObject".
- ^ "Справочное руководство GObject - стабильная".
- ^ "glib-mkenums, Справочное руководство по GObject".
- ^ «Как определить и реализовать новый GObject». gnome.org. Получено 27 июля 2013.
- ^ "c ++ - Почему была создана система GObject?". Переполнение стека. Получено 2019-11-16.
- ^ «Распределение памяти: Справочное руководство по GLib». developer.gnome.org. Получено 2019-11-16.
- ^ «Распределение памяти: Справочное руководство по GLib». developer.gnome.org. Получено 2019-11-17.