GObject

редактировать
GObject
Разработчик (и) Проект GNOME
Первоначальный выпуск11 марта 2002 г. ; 18 лет назад (11.03.2002)
Стабильный выпуск 2.64.4 (2 июля 2020 г.; 3 месяца назад (2020-07-02))
Написано наC
Операционная система Кросс-платформенный
Доступен вМногоязычном
Типе Программная библиотека
Лицензия GNU LGPL
Веб-сайтразработчик.gnome.org / gobject / stable /
Поскольку библиотека GNU C служит оболочкой для ядра Linux системных вызовов, то же самое делают и библиотеки в комплекте в GLib (GObject, Glib и GIO ) служат дополнительными оболочками для своих конкретных задач.

Система объектов GLib, или GObject, является бесплатной программной библиотекой, обеспечивающей портативную объектную систему и прозрачную межъязыковую совместимость. GObject разработан для использования как непосредственно в программах C для предоставления объектно-ориентированных API-интерфейсов на основе C, так и через привязки к другим языкам для обеспечения прозрачного межъязыкового взаимодействия, например PyGObject.

Содержание
  • 1 GObject Introspection
  • 2 История
  • 3 Связь с GLib
  • 4 Система типов
    • 4.1 Основные типы
    • 4.2 Производные типы
  • 5 Обмен сообщениями система
  • 6 Реализация класса
  • 7 Использование
  • 8 Сравнение с другими объектными системами
  • 9 См. также
  • 10 Ссылки
  • 11 Внешние ссылки
GObject Introspection
History

В зависимости только от GLib и libc, GObject является краеугольным камнем GNOME и используется во всех библиотеках GTK, Pango, ATK и большинстве высокоуровневых библиотек GNOME, таких как GStreamer и Приложения. До GTK + 2.0 код, аналогичный GObject, был частью кодовой базы GTK. (Имя «GObject» еще не использовалось - общий базовый класс назывался GtkObject.)

В выпуске GTK + 2.0 объектная система была извлечена в отдельную библиотеку из-за его общая полезность. При этом большинство частей класса GtkObject, не относящихся к GUI, были перемещены в GObject, новый общий базовый класс. Библиотека GObject, существующая как отдельная библиотека с 11 марта 2002 г. (дата выпуска GTK + 2.0), теперь используется многими программами без графического интерфейса пользователя, такими как командная строка и server <87.>приложения.

Хотя GObject имеет свой собственный отдельный набор документации и обычно компилируется в свой собственный файл разделяемой библиотеки, исходный код GObject находится в Дерево исходных текстов GLib и распространяется вместе с GLib. По этой причине GObject использует номера версий GLib и обычно упаковывается вместе с GLib (например, Debian помещает GObject в свое семейство пакетов libglib2.0).

Система типов

На самом базовом уровне инфраструктуры GObject лежит общая и динамическая система типов , называемая GType. Система GType содержит описание всех объектов во время выполнения, позволяющее связать код для облегчения привязки нескольких языков. Система типов может обрабатывать любую унаследованную структуру класса в дополнение к неклассифицированным типам, таким как непрозрачные указатели, строки и целые числа разного размера. и числа с плавающей запятой.

Система типов знает, как копировать, присваивать и уничтожать значения, принадлежащие любому из зарегистрированных типов. Это тривиально для таких типов, как целые числа, но многие сложные объекты подсчитываются по ссылкам, а некоторые являются сложными, но не с подсчетом ссылок. Когда система типов «копирует» объект с подсчетом ссылок, она обычно просто увеличивает счетчик ссылок, тогда как при копировании сложного объекта без подсчета ссылок (например, строки) она обычно создает фактическую копию с помощью выделение памяти.

Эта базовая функциональность используется для реализации GValue, типа универсального контейнера, который может содержать значения любого типа, известного системе типов. Такие контейнеры особенно полезны при взаимодействии с динамически типизированными языковыми средами, в которых все собственные значения находятся в таких контейнерах с тегами типа.

Основные типы

Типы, не имеющие связанных классов, называются неклассовыми. Эти типы вместе со всеми типами, которые соответствуют какой-либо форме, известны как фундаментальные типы: типы, от которых происходят все другие типы. Они составляют относительно замкнутый набор, но хотя от обычного пользователя не ожидается, что он создаст свои собственные фундаментальные типы, возможность существует и использовалась для создания пользовательских иерархий классов, т. Е. Иерархий классов, не основанных на класс GObject.

Начиная с GLib 2.9.2, неклассифицированные встроенные фундаментальные типы:

  • пустой тип, соответствующий C void(G_TYPE_NONE);
  • типы соответствующие знаковым и беззнаковым C char, int, longи 64-битным целым числам (G_TYPE_CHAR, G_TYPE_UCHAR, G_TYPE_INT, G_TYPE_UINT, G_TYPE_LONG, G_TYPE_ULONG, G_TYPE_INT64, и <152_TYPE_T64и <152_T_TYPE_64 логический тип (G_TYPE_BOOLEAN);
  • тип перечисления и тип «флаги», оба соответствуют типу C enum, но отличаются тем, что последний используется только для битовых полей (G_TYPE_ENUMи G_TYPE_FLAGS);
  • типы для одинарной и двойной точности IEEE float, соответствующие C floatи double(G_TYPE_FLOATи G_TYPE_DOUBLE);
  • тип строки, соответствующий C char *(G_TYPE_STRING);
  • тип непрозрачного указателя, соответствующий C пусто *(G_TYPE_POINTER).

Классифицированные встроенные фундаментальные типы:

  • тип базового класса для экземпляров GObject, корень стандартного дерева наследования классов (G_TYPE_OBJECT)
  • тип базового интерфейса, аналогичный типу базового класса, но представляющий корень стандартного дерева наследования интерфейса (G_TYPE_INTERFACE)
  • тип для упакованных структур, которые используются для обертывания простых объекты значений или посторонние объекты в «ящиках» со счетчиком ссылок (G_TYPE_BOXED)
  • тип для «объектов спецификации параметров», которые используются в GObject для описания метаданных для свойств объекта (G_TYPE_PARAM).

Типы, которые могут быть созданы автоматически системой типов, называются инстанцируемыми. Важной характеристикой этих типов является то, что первые байты любого экземпляра всегда содержат указатель на структуру класса (форма виртуальной таблицы ), связанную с типом экземпляра. По этой причине любой инстанцируемый тип должен быть классифицирован. Напротив, любой неклассированный тип (такой как целое число или строка) не должен быть инстанцируемым. С другой стороны, большинство классифицированных типов могут создавать экземпляры, но некоторые, например типы интерфейсов, нет.

Производные типы

Типы, производные от встроенных фундаментальных типов GObject, делятся примерно на четыре категории:

Перечислимые типы и типы «флагов»
В как правило, каждый перечислимый тип и каждый тип битового поля на основе целых чисел (т.е. каждый тип enum), который желают использовать каким-либо образом, связанным с объектной системой - например, как тип объекта свойство - должно быть зарегистрировано в системе типов. Обычно код инициализации, отвечающий за регистрацию этих типов, генерируется автоматизированным инструментом glib-mkenumsи сохраняется в отдельном файле.
Типы в штучной упаковке
Некоторые структуры данных, которые слишком просты для того, чтобы их можно было сделать полноценными типами классов (со всеми возникающими накладными расходами), возможно, все же потребуется зарегистрировать в системе типов. Например, у нас может быть класс, к которому мы хотим добавить свойство background-color, значения которого должны быть экземплярами структуры, которая выглядит как struct color {int r, g, b; }. Чтобы избежать создания подкласса GObject, мы можем создать упакованный тип для представления этой структуры и предоставить функции для копирования и освобождения. GObject поставляется с несколькими упакованными типами, обертывающими простые типы данных GLib. Другое использование упакованных типов - это способ обернуть посторонние объекты в помеченный контейнер, который система типов может идентифицировать и знать, как копировать и освобождать.
Типы непрозрачных указателей
Иногда, для объекты, которые не нужно ни копировать, ни подсчитывать ссылки, ни освобождать, даже упакованный тип будет излишним. Хотя такие объекты можно использовать в GObject, просто рассматривая их как непрозрачные указатели (G_TYPE_POINTER), часто бывает хорошей идеей создать производный тип указателя, документируя тот факт, что указатели должны ссылаться на определенный вид
Типы классов и интерфейсов
Большинство типов в приложении GObject будут классами - в обычном объектно-ориентированном смысле слова - производными напрямую или косвенно из корневого класса, GObject. Существуют также интерфейсы, которые, в отличие от классических интерфейсов в стиле Java, могут содержать реализованные методы. Таким образом, интерфейсы GObject можно описать как миксины.
Система обмена сообщениями

Система обмена сообщениями GObject состоит из двух взаимодополняющих частей: замыканий и сигналов.

Closures
Замыкание GObject - это обобщенная версия обратного вызова. Существует поддержка замыканий, написанных на C и C ++, а также на произвольных языках (при наличии привязок). Это позволяет запускать код, написанный (например) на Python и Java через замыкание GObject.
Сигналы
Сигналы - это основной механизм, с помощью которого вызываются замыкания. Объекты регистрируют слушателей сигналов с помощью системы типов, определяя соответствие между заданным сигналом и заданным замыканием. При выдаче зарегистрированного сигнала происходит закрытие этого сигнала. В GTK все собственные события графического интерфейса (такие как движение мыши и действия клавиатуры) могут генерировать сигналы GObject, на которые слушатели могут потенциально действовать.
Реализация класса

Каждый класс GObject реализуется как минимум двумя структурами: структура класса и структура экземпляра.

Структура класса
Структура класса соответствует vtable класса C ++. Он должен начинаться со структуры классов суперкласса. После этого он будет содержать набор указателей на функции - по одному на каждый виртуальный метод класса. Для имитации членов класса можно использовать переменные, зависящие от класса.
Структура экземпляра
Структура экземпляра, которая будет существовать в одной копии для каждого экземпляра объекта, должна начинаться со структуры экземпляра суперкласс (это гарантирует, что все экземпляры начинаются с указателя на структуру класса, поскольку все фундаментальные экземпляры типов разделяют это свойство). После данных, принадлежащих суперклассу, структура может содержать любые переменные, зависящие от экземпляра, соответствующие переменным-членам C ++.

Определение класса в инфраструктуре GObject является сложной задачей, требующей большого количества шаблонного кода, такие как ручные определения макросов приведения типов и неясные заклинания регистрации типов. Кроме того, поскольку структура C не может иметь модификаторы доступа, такие как «общедоступный», «защищенный» или «частный», необходимо использовать обходные пути для обеспечения инкапсуляции. Один из подходов состоит в том, чтобы включить указатель на личные данные - обычно называемые _priv- в структуру экземпляра. Частная структура может быть объявлена ​​в общедоступном файле заголовка, но определена только в файле реализации, в результате чего частные данные будут непрозрачными для пользователей, но прозрачными для разработчика. Если частная структура зарегистрирована в GType, она будет автоматически выделена объектной системой. В самом деле, нет необходимости даже включать указатель _priv, если кто-то желает использовать заклинание G_TYPE_INSTANCE_GET_PRIVATEкаждый раз, когда требуются личные данные.

Для решения некоторых из этих сложностей существует несколько языков более высокого уровня, которые исходный код компилирует в GObject на C. В языке программирования Vala используется синтаксис в стиле C # и предварительно обрабатывается в код vanilla C. GObject Builder, или GOB2, предлагает синтаксис шаблона, напоминающий Java.

Использование

Комбинация C и GObject используется во многих успешных бесплатных программах, таких как рабочий стол GNOME, инструментарий GTK и программа обработки изображений GIMP.

Хотя многие приложения GObject полностью написаны на C, система GObject хорошо соответствует системам собственных объектов многих других языков, таких как C ++, Java, Ruby, Python, Common Lisp и .NET / Mono. В результате обычно относительно безболезненно создавать языковые привязки для хорошо написанных библиотек, использующих инфраструктуру GObject.

Написание кода GObject в первую очередь на C, однако, относительно многословно. Для изучения библиотеки требуется много времени, и программисты, имеющие опыт работы с высокоуровневыми объектно-ориентированными языками, часто находят несколько утомительным работать с GObject на C.Например, создание подкласса (даже просто подкласс GObject) может потребовать написания и / или копирования больших объемов стандартного кода. Однако использование Vala, языка, который предназначен в первую очередь для работы с GObject и который конвертируется в C, вероятно, сделает работу с GObject или написание библиотек на основе GObject более приятной.

Хотя на самом деле они не являются объектами первого класса (в GType нет реальных метатипов), метаобъекты, такие как классы и интерфейсы, создаются приложениями GObject во время выполнения, и обеспечить хорошую поддержку самоанализу. Интроспективные возможности используются языковыми привязками и приложениями для разработки пользовательского интерфейса, такими как Glade, чтобы делать такие вещи, как загрузка разделяемой библиотеки, которая предоставляет класс GObject - обычно своего рода виджет , в случае Glade - а затем получить список всех свойств класса с информацией о типе и строками документации.

Сравнение с другими объектными системами

Поскольку GObject предоставляет в основном полную объектную систему для C, его можно рассматривать как альтернативу языкам, производным от C, таким как C ++ и Цель-C. (Хотя оба они также предлагают множество других функций, помимо соответствующих объектных систем.) Легко наблюдаемое различие между C ++ и GObject заключается в том, что GObject (как и Java) не поддерживает множественное наследование.

Использование GObject GLib функция выделения памяти g_malloc () заставит программу безоговорочно завершиться после исчерпания памяти, в отличие от библиотеки C malloc (), C ++ new и других распространенных распределителей памяти, которые позволяют программе справляться с ситуациями нехватки памяти или даже полностью восстанавливаться после них без простого сбоя. Это, как правило, работает против включения GObject в программное обеспечение, где важна устойчивость перед лицом ограниченной памяти или где обычно обрабатывается очень много или очень большие объекты. G_try_new () может использоваться, когда с большей вероятностью произойдет сбой выделения памяти (например, для большого объекта), но это не может гарантировать, что выделение не завершится сбоем в другом месте кода.

Еще одно важное отличие заключается в что, хотя 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. При использовании / gtkmm, официальных оболочек C ++ для Glib / GTK соответственно, родственный проект libsigc ++ позволяет легко использовать базовые сигналы GObject с использованием стандартного C ++. Конечно, другие реализации сигналов доступны почти на всех платформах, хотя иногда требуется дополнительная библиотека, например Boost.Signals2 для C ++.

См. Также
  • Портал бесплатного программного обеспечения с открытым исходным кодом

.

Ссылки
Внешние ссылки
Последняя правка сделана 2021-05-21 09:15:33
Содержание доступно по лицензии CC BY-SA 3.0 (если не указано иное).
Обратная связь: support@alphapedia.ru
Соглашение
О проекте