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.