Кіріспе

GLib Object System немесе GObject – портативті объект жүйесі және тілдер арасындағы мөлдір өзара іс-қимыл мүмкіндігін ұсынатын ақысыз бағдарламалық кітапхана. GObject C бағдарламаларында объектіге бағытталған C негізіндегі API-лерді тікелей пайдалану үшін, сондай-ақ басқа тілдерге байланыстар арқылы, мысалы PyGObject, мөлдір тілдер арасындағы өзара іс-қимыл мүмкіндігін қамтамасыз ету үшін жасалған.

Тарих

Тек GLib және libc-ге ғана байланысты, GObject – GNOME-ның негізгі тасы болып табылады және GTK, Pango, ATK, сондай-ақ GStreamer және қосымшалар сияқты GNOME-ның жоғары деңгейдегі кітапханаларында кеңінен қолданылады. GTK+ 2.0 нұсқасынан бұрын GObject-ке ұқсас код GTK код базасының бір бөлігі болған. (Ол кезде «GObject» атауы қолданылмаған, ортақ базалық сынып GtkObject деп аталған.) GTK+ 2.0 нұсқасы шығарылғанда, объектілер жүйесі оның жалпы қолданылу мүмкіндігіне байланысты жеке кітапханаға бөлініп шығарылды. Осы процесте GtkObject класының графикалық интерфейске қатысы жоқ көптеген бөліктері GObject-ке, жаңа ортақ базалық сыныпқа көшірілді. 2002 жылдың 11 наурызынан бері (GTK+ 2.0 нұсқасының шығу күнінен бастап) жеке кітапхана ретінде қолданылып келе жатқан GObject кітапханасы қазір көптеген графикалық интерфейсі жоқ бағдарламалар, мысалы, командалық жол және серверлік бағдарламалармен де пайдаланылады.

GLib-мен байланысы

GObject жеке құжаттама жинағына және әдетте өздік ортақ кітапхана файлына жинақталса да, GObject-тің бастапқы коды GLib бастапқы кодының ағашында орналасқан және GLib-пен бірге таратылады. Сондықтан GObject GLib нұсқа нөмірлерін пайдаланады және көбінесе GLib-пен бірге жинақталады (мысалы, Debian GObject-ті libglib2.0 пакеттері отбасына қосады).

Түр жүйесі

GObject фреймворкінің ең негізгі деңгейінде GType деп аталатын жалпы және динамикалық типтік жүйе жатыр. GType жүйесі барлық нысандардың орындалу кезіндегі сипаттамасын сақтайды, бұл бірнеше тілдің байланысын жеңілдетуге көмектесетін аралық кодты құруға мүмкіндік береді. Типтік жүйе кез келген жалғыз мұрагерлік кластық құрылымды, сондай-ақ кластарға жатпайтын типтерді – мөлдір емес көрсеткіштерді, жолдарды, әртүрлі өлшемдегі бүтін сандарды және қозғалатын нүктелі сандарды басқара алады. Типтік жүйе тіркелген кез келген типке жататын мәндерді көшіру, тағайындау және жою қалай жүргізілетінін біледі. Бұл бүтін сандар сияқты типтер үшін қарапайым, бірақ көптеген күрделі нысандар сілтеме санауымен басқарылады, ал кейбіреулері күрделі болғанымен сілтеме санауы жоқ. Типтік жүйе сілтеме санауы бар нысанды көшіргенде, әдетте оның сілтеме санауын арттырады, ал күрделі, сілтеме санауы жоқ нысанды (мысалы, жолды) көшіргенде, жадты бөліп, нақты көшірме жасайды. Бұл негізгі функционалдық GValue құру үшін қолданылады, ол типтік жүйеге белгілі кез келген типтің мәндерін сақтай алатын жалпы контейнердің түрі. Мұндай контейнерлер, әсіресе, барлық түпнұсқалық мәндер осындай типтік таңбаланған контейнерлерде сақталатын динамикалық типтегі тілдермен өзара әрекеттескенде өте пайдалы.

Хабарламалар жүйесі

GObject хабарлау жүйесі екі бір-бірін толықтыратын бөліктен тұрады: жабылулар және сигналдар. Жабылулар GObject жабылуы – кері шақырудың (callback) жалпыланған түрі. C және C++ тілдерінде жазылған жабылуларға, сондай-ақ кез келген тілдерде (байланыстар болған жағдайда) қолдау бар. Бұл, мысалы, Python және Java тілдерінде жазылған кодты GObject жабылуы арқылы шақыруға мүмкіндік береді. Сигналдар Сигналдар – жабылуларды іске қосатын негізгі механизм. Объектілер сигналдарды тыңдаушыларды типтік жүйеде тіркейді, сонда берілген сигнал мен жабылу арасындағы байланыс көрсетіледі. Тіркелген сигнал шығарылғанда, сол сигналға сәйкес жабылу шақырылады. GTK-да барлық түпнұсқа GUI оқиғалары (мысықтың қозғалысы және пернетақтаның әрекеттері сияқты) тыңдаушылар үшін GObject сигналдарын тудыра алады.

Сыныпты іске асыру

Әр GObject класы кем дегенде екі құрылыммен іске асырылады: сынып құрылымы және инстанция құрылымы. Сынып құрылымы C++ класының vtable-ына сәйкес келеді. Ол жоғары кластың сынып құрылымынан басталуы керек. Содан кейін, ол кластың әрбір виртуалды әдісі үшін функция көрсеткіштері жиынтығын қамтиды. Сыныпқа тән айнымалыларды сынып мүшелерін эмуляциялау үшін пайдалануға болады. Инстанция құрылымы Бір инстанцияда бір дана болатын инстанция құрылымы жоғары кластың инстанция құрылымынан басталуы керек (бұл барлық инстанциялар сынып құрылымына көрсеткішпен басталатынын қамтамасыз етеді, өйткені барлық негізгі инстанцияланатын типтерде осы қасиет болады). Жоғары кластың деректерінен кейін құрылым инстанцияға тән кез келген айнымалыларды қамтамасыз ете алады, бұл C++ мүшелік айнымалыларына сәйкес келеді. GObject фреймворкінде класты анықтау күрделі, көп көлемде стандартты кодты, мысалы, типтік түрлендіру макростарын қолмен анықтау және түсініксіз типтік тіркеу амалдарын қажет етеді. Сонымен қатар, C құрылымында «public», «protected» немесе «private» сияқты кіру модификаторлары болмайтындықтан, инкапсуляцияны қамтамасыз ету үшін шешімдер табу қажет. Бір тәсіл – инстанция құрылымына әдетте «priv» деп аталатын жеке деректерге көрсеткішті қосу. Жеке құрылымды ашық бас файлда жариялауға болады, бірақ оны тек іске асыру файлында ғана анықтауға болады, нәтижесінде жеке деректер пайдаланушылар үшін жасырын, бірақ іске асырушы үшін ашық болады. Егер жеке құрылым GType-те тіркелген болса, ол объект жүйесімен автоматты түрде бөлінеді. Шындығында, егер жеке деректер қажет болған сайын «G_TYPE_INSTANCE_GET_PRIVATE» амалын қолдануға дайын болса, «priv» көрсеткішін қосудың қажеті жоқ. Осы күрделіліктердің кейбірін шешу үшін GObject-ке бастапқы кодтан код құрастыратын бірнеше жоғары деңгейдегі тілдер бар. Vala бағдарламалау тілі C# стильіндегі синтаксисті пайдаланады және қарапайым C кодына алдын ала өңделеді. GObject Builder немесе GOB2 Java-ны еске түсіретін үлгі синтаксисін ұсынады.

Нысанның өзіндік зерттеуі

GObject интроспекциясы (қысқартылған GIR) — GObject пайдаланатын C кітапханалары мен тілдік байлаулар арасындағы сыртқы функция интерфейсі аралық қабат, мысалы, GTK үшін тілдік байлаулар тізімі.

Қолданылуы

C және GObject комбинациясы GNOME жұмыс үстелі, GTK құралдар жиынтығы және GIMP кескінді өңдеу бағдарламасы сияқты көптеген табысты ашық кодты жобаларда қолданылады. GObject қолданбаларының көптеген түрлері толығымен C тілінде жазылғанмен, GObject жүйесі C++, Java, Ruby, Python, Common Lisp және NET/Mono сияқты көптеген басқа тілдердің туа табиғатындағы объектілік жүйелерімен үйлеседі. Осының нәтижесінде, GObject фреймворкін пайдаланатын жақсы жазылған кітапханалар үшін тілдік байланыстар жасау көбінесе қиындық тудырмайды. Дегенмен, GObject кодын бастапқыда C тілінде жазу көбінесе көлемді болады. Кітапхананы меңгеру көп уақытты қажет етеді, ал жоғары деңгейдегі объектіге бағытталған тілдерде тәжірибесі бар бағдарламашылар GObject-пен C тілінде жұмыс істеуді кейде мазасыздық тудыратын деп санайды. Мысалы, субкласс жасау (тіпті GObject-тің бір ғана субклассы болса да) үлкен мөлшерде кодты жазуды және/немесе көшіруді талап етуі мүмкін. Алайда, GObject-пен жұмыс істеуге және GObject-ке негізделген кітапханаларды жазуға арналған Vala тілін пайдалану, C тіліне түрлендірілетін, жұмысты ыңғайлырақ етеді. Олар нақты бірінші сыныптық объектілер болмаса да (GType-де нақты метатиптер жоқ), GObject қолданбалары орындалу кезінде кластар мен интерфейстер сияқты метаобъектілерді жасайды және интроспекция үшін жақсы қолдау көрсетеді. Интроспекция мүмкіндіктері тілдік байланыстар мен Glade сияқты пайдаланушы интерфейсін жобалау қолданбаларында қолданылады, бұл GObject класын ұсынатын ортақ кітапхананы жүктеу сияқты нәрселерді жасауға мүмкіндік береді, әдетте Glade жағдайында белгілі бір виджет, содан кейін кластың барлық қасиеттерінің тізімін, түр туралы ақпаратты және құжаттама жолдарымен бірге алуға болады.

Басқа объект жүйелерімен салыстыру

GObject C үшін көбінесе толыққанды нысандық жүйемен қамтамасыз ететіндіктен, оны C++, Objective C сияқты C-ден туындаған тілдерге балама ретінде қарастыруға болады. (Дегенмен, екеуі де сәйкес нысандық жүйелерден өзге көптеген мүмкіндіктерді ұсынады.) C++ және GObject арасындағы айқын айырмашылық – GObject (Java сияқты) көп мұрагерлікті қолдамайды. GObject GLib-тің g_malloc жадты бөлу функциясын пайдалануы бағдарламаны жад жетіспесе, міндетті түрде тоқтатуға мәжбүрлейді, ал C кітапханасының malloc, C++-тың new және басқа да кең таралған жад бөлушілер бағдарламаға жадтан тыс жағдайларды өңдеуге немесе тіпті толыққанды қалпына келтіруге мүмкіндік береді, жай ғана құлаусыз. Бұл GObject-ті жадтың шектеулігіне төзімділік маңызды немесе көптеген немесе өте үлкен нысандар жиі қолданылатын бағдарламалық құралдарға енгізбеуге қарсы әрекет етеді. g_try_new жадты бөлу сәтсіз болуы мүмкін болған жағдайда (мысалы, үлкен нысан үшін) қолданылуы мүмкін, бірақ бұл кодтың басқа бөлігінде бөлу сәтсіз болмайтынын кепілдемейді. Тағы бір маңызды айырмашылық – C++ және Objective C жеке тілдер болса, GObject – тек кітапхана және жаңа синтаксис немесе компилятор мүмкіндіктерін енгізбейді. Мысалы, GObject негізінде C кодын жазғанда, көбінесе нақты түрлендіруді орындау қажет. Сондықтан, “C with GObject”, сондай-ақ “glib flavored C” деп аталатын, қарапайым C-ден өзге тіл ретінде қарастырылатын C, Objective C сияқты қарапайым C-нің қатаң жоғары жиыны болып табылады, бірақ C++-тан ерекшеленеді. Барлық C++ компиляторларында жұмыс істейтін стандартты ABI жоқ платформаларда (әдетте бұл жағдай емес, өйткені Itanium ABI немесе Microsoft ABI көбінесе қолданылады), бір C++ компиляторымен құрастырылған кітапхана басқа компилятормен құрастырылған кітапхананы шақыра алмайды. Мұндай үйлесімділік қажет болса, C++ әдістері қарапайым C функциялары ретінде экспортталуы керек, бұл C++ нысандық жүйесінің мақсатын ішінара жояды. Бұл мәселе, әртүрлі C++ компиляторлары экспортталған барлық символдардың бірегейлігін қамтамасыз ету үшін әртүрлі атауларды өзгертуді қолдануынан туындайды. (Бұл қажет, өйткені, мысалы, екі түрлі класс бірдей аталатын мүшелік функцияларға ие болуы мүмкін, бір функция атауы бірнеше рет жүктелуі мүмкін немесе бірдей аталатын функциялар әртүрлі атау кеңістіктерінде пайда болуы мүмкін, бірақ объектілік кодта мұндай қайталауларға жол берілмейді.) Керісінше, C артық жүктеуді немесе атау кеңістіктерін қолдамайтындықтан, C кітапханаларының авторлары экспортталған атауларының жаһандық бірегейлігін қамтамасыз ету үшін әдетте ашық префикстерді пайдаланады. Сондықтан, нысанға бағытталған болса да, C тілінде жазылған GObject негізіндегі кітапхана қандай компилятор қолданылғанына қарамастан, әрқашан бірдей сыртқы символ атауларын қолданады. Бәлкім, ең маңызды айырмашылық – GObject-тің сигналдарға (басқа тілдерде оқиғалар деп аталады) баса назар аударуы. Бұл басымдық GObject GUI құралдар жиынтығының қажеттіліктерін қанағаттандыру үшін арнайы жасалғандықтан туындайды. Көптеген нысанға бағытталған тілдер үшін сигнал кітапханалары бар болса да, GObject жағдайында ол нысандық жүйеге енгізілген. Осыған байланысты, әдеттегі GObject қосымшасы сигналдарды GObject емес қосымшаға қарағанда әлдеқайда көп пайдаланады, бұл GObject компоненттерін қарапайым C++ немесе Java қолданатындарға қарағанда әлдеқайда жақсы капсулаланған және қайта пайдалануға болатын етеді. Егер glibmm/gtkmm, Glib/GTK-ға арналған ресми C++ орамаларын қолданса, туысқан жоба libsigc++ стандартты C++ қолдана отырып, негізгі GObject сигналдарын оңай пайдалануға мүмкіндік береді. Әрине, сигналдардың басқа да іске асырылымдары барлық платформаларда қол жетімді, бірақ кейде қосымша кітапхана қажет, мысалы Boost.Signals2 C++ үшін.