見出し画像

Retro-gaming and so on

GLib入門 落ち穂拾い編

C言語嫌いでC言語が不得手にも関わらず「GLib入門」なんて苦しんでやってきたが、これが本当の最終回だ。最初の回で「誰かC言語のエキスパート(C言語脳ではない)がマトモなGLib入門を書いてくれりゃイイのに」って書いたが、その気持ちは相変わらず変わっていない。
単にこの記事連は「(GLib紹介の)取っ掛かりになればエエな」と言う願いだけで構成されている。事実、GLibに関して纏まって紹介されてる記事は、ぶっちゃけ、英語圏のWebページも含めてほぼ存在しない、んだ。
しかし、(個人的事情で)中断を挟んだにも関わらず、GLibの主要な「抽象データ型」の紹介はやっとこさ前回で全て終わった。これらは「モダンなプログラミング言語が備えた抽象データ型」としてはポピュラーだが、素のC言語では「欠けてる」モノで、GLibを入手した事で、やっとこさC言語は「モダンなプログラミング言語の領域」に入ってこれる。
残るは落ち穂拾い、としてGLibに備えられたユーティリティ関数を少々紹介していこう。

本来では、今まで紹介してきたGLibの抽象データ型関連の操作関数は、GLibではメソッドと呼んでいる。いや、C言語にはオブジェクト指向言語で言うトコのメソッドは無い。単にGLibでは「抽象データ型操作目的の関数」をメソッド、と呼んでるだけ、だ。
一方、GLibにはユーティリティ関数としてFunctionsと言うのを用意している。元々GLibはC言語標準装備のstdio.hstdlib.hstring.h等を取り込み、ラップしたり、あるいはもっと高機能の関数に置き換えたりしてる。例えば頻出のg_printなんかはそういった関数の一つだ。
例えばここここで見たようなパターンで、C言語標準のstrtokを使うくらいだったら、場合によってはGLibのg_strsplitを使った方が物事は遥かに簡単になる、って事だ。



g_strsplitの動作自体はPythonの文字列に対するsplitメソッドに近い。第一引数にgchar*型の文字配列、第二引数に区切り文字、そして第三引数に「分割数を指定」するが、1以下の数値を指定すると第一引数に与えられたgchar*型の文字配列をキッカリハッキリまるっと分割する(つまり、任意の数を与えればその数で分割可能だ、と言う事だ)。
返り値はポインタのポインタ、っつーか、概念的にはgchar*型の配列を返す(実際は違うけど・笑)。んでその時点で文字配列はバラバラに分解されている。
あとは、g_strsplitを使うと動的にメモリが確保されるんで、最後にg_strfree_vを使ってメモリを開放する。
とまぁ、素のC言語が持ってるライブラリを使うより色々と便利になってるのがGLibのFunctionsだ。ただし、数がかなり多い(笑)。従って、当然ながらここで全部紹介は出来ない。

ところで、何度も言うがGLibの入門サイトなぞ世界中探そうがまず無い。それどころか、解説書の類も存在しない、んだ。
唯一の例外としてGLibに対しての言及がある本、ってのが、知ってる限り、日本で上梓された次の本だ。

 
「え?GTK+って書いてるじゃん?GLib関係ないじゃん?」

って早合点する人の為に、今更ながら、改めてGLibの由来を話しておこう。
元々、GTK+と言うのは、フリーソフト版Photoshopって言って良い高機能画像編集ソフト、GIMPの為に作られたライブラリだ。


GIMP

GIMPは商用であるAdobe PhotoShopに対抗出来る程高機能なソフトウェアだ。しかしながら、正直な事を言うと、フリーソフトウェアにありがちな、「高機能だけど使い勝手は良くない」と言うトコがある。機能を詰め込めるだけ詰め込んで、ユーザーインターフェースに関しては「知らんがな」ってタイプのソフトウェアなんだな(笑)。
ただ、有償で高価なPhotoShopを避けてフリーソフトウェアを探してる人にはMUSTと言えるソフトウェアだ。色んな画像編集が可能なソフトウェアで、フリーソフトウェアとしては代表的なソフトウェアと言えるだろう。Windows版もある。
このGIMPを作成する際に作られたライブラリがGTKだ。GTKはGIMPを作成する為に作られたわけで、名前もThe GIMP Took Kitってのがその由来になる。
さて、このGTKだが、元々は単に画像編集ソフトGIMPを実装する為だけ、に作られたライブラリだったんだけど、あまりに出来が良かったんで、そのうち、何故かLinuxのデスクトップ環境をこれで作ろう、と言う話になったんだ。当時、Linuxでは既にKDEと言うデスクトップ環境が人気だったんだけど、それを作成してるQtと言うGUI作成ツールのライセンスがちとややこしくて、気楽に使ったり出来ない、って状態だったわけ(現在はQtのライセンスは緩くなっている)。つまり、「もっと自由なデスクトップ環境が欲しい」と。
ここでGTKと言うGUI作成ツールを使って作ったGNOMEと言うデスクトップ環境が登場したわけだ。そしてLinuxでは、KDEに対抗する一大デスクトップ環境として性徴成長する。

GNOME デスクトップ環境

そして、このGIMP/GNOMEと言うツールを作ったGTKと言うツールキットの中にGLibが存在する。言い換えると「GUIソフトを作る」目的のツールキットの中で、汎用的なライブラリ、として成立したのがGLibなんだ。結果、GUIのデスクトップ環境やGIMPと言うソフトウェアの中でGLibは粛々と各種「抽象データ型」を作り出してそれら対象に演算してるわけだな。
だから実用性もグンバツ、のライブラリなわけ。
そしてLinuxでLinuxネイティヴのGUI(つまりクロスプラットフォーム・・・Windowsに持っていったりMacに持っていったり、を考えない)をやりたい、って言った場合、まずはGTKを勉強せざるを得ないわけだ。言い換えるとGTKは「LinuxのWindows API」だと考えていい(笑)。
そしてGTKを勉強する以上、中に含まれるGLibも勉強せなアカン・・・となるわけ。既にGLibはGLibで単独で存在出来るんだけど、GTKの屋台骨を支えている大事なライブラリなんだよ。
つまり、「LinuxでGUIアプリケーションを作ってみたい」って人も上記の本に類する本を買ってみてもいいだろう・・・GTKもC言語で書かれたライブラリだが、Linuxで生まれたプログラミング言語では、GTKへのバインディングを備えたモノが多い。例えばScheme処理系GaucheでもGTKへのバインディングを持っていて、「LispはGUIアプリを書くのに不向き」と言ったイメージとは違う結果になるだろう。そしてC言語でプログラムを書かないにせよ、上記に類する本で「どんな風にGTKを使うのか」と言う事を学ぶ事は出来るはずだ・・・そしてGTKにもGUIビルダはあるんで、殆どコードを書く必要はないハズだ。


Glade。マウスを使ってこれでUIを組み上げる。なお、PythonなんかもGTKへのバインディングが提供されているし、Rustでもある

まぁ、僕自身はクロスプラットフォームなwxWidgetsの方が好きなんだが・・・・・・。

なお、岩手大学の方で上記の「入門GTK+」の無料PDF版が公開されている。これを入手してもいいだろう・・・・・・岩手大学は凄く、少なくともWeb上の資料を見る限り、2015年から2017年の3年に渡って、理工系学部の3年生対象に、「ソフトウェア設計及び演習」と言う授業でGTKを教えてたらしい。これはスゴイ。元々「立ってるモノは親でも使え」と言う思想を持ったUNIXだったのに、MS-DOSを経由して以降、C言語教育は「極端なDIYを強要する」ようになってしまった。外部ライブラリを使う、って慣習を教えなくなってしまったんだけど、岩手大学では「既存のライブラリを徹底活用する」と言うUNIX思想に準じた教育を行ってたんだな。この時期に岩手大学で学んだ人は凄腕のハッカーに育ったんじゃなかろうか。
残念ながら、時代の流れなのか、同講座は2018年以降はJavaScriptを用いた授業へと変遷した模様だ。返す返すも残念だ。

ところで、GLibのFunctionsの一例として、「入門GTK+」で紹介されているコード例を示そう(※1)。これはUNIXで言うとlsコマンド、MS-DOSで言うとdirコマンドっぽいプログラムだ。「プログラミング言語C」でも最終章でUNIXのlsコマンドの仕組みがある程度解説されているが、それでもかなり長いソースだ。
元々、素のC言語でファイルないしはディレクトリ(フォルダ)を扱うのはメンド臭いんだ。

 
一方、GLibのFunctionsを使った実装は異様に短い。結果、「実用性」に重きを置いてるGLibだと良い抽象化を施したユーティリティ関数を提供してるんだ、と言う実例になるんじゃないか。



  • GDir: GLibで定義されてるディレクトリ(フォルダ)を表す抽象データ型。これが無いと自分で構造体で定義せねばならない、と言う事をK&Rは示していて、これが既に定義されてる事で関連する様々な「面倒くさい」コーディングが省略出来るわけだ。
  • g_dir_open: その名の通り、ディレクトリ(フォルダ)を開く関数。第一引数はそのディレクトリのパス、第二引数は0(将来的に拡張される可能性があるらしい)、第3引数はNULLを指定する(GErrorと言うのもあるらしいが詳細が分からず)。返り値はGDir*になる。これもK&Rではopendirとして実装されてるが、長い(笑)。
  • g_dir_read_name: 指定したディレクトリ(GDir)からガンガンファイル名を読み込む一引数関数。引数にはディレクトリ名を指定し、返り値はgchar*になる。K&Rでのreaddir関数にあたる。
  • g_build_filename: 指定したディレクトリとファイル名からパス名を生成する関数だが可変長引数の関数だ。引数に与えられた情報からOSに即したパスを合成する(大まかに言うとUNIXの/とWindowsの\、とか)。返り値はgchar*。
  • g_file_test: 第二引数で与えられた「テスト」に対して第一引数に与えられたブツが通るかどうか真偽値(gboolean)を返す関数。テストは5種類程あり、上の例だと第一引数がディレクトリかどうかテストしている。
  • g_dir_close: ディレクトリを閉じる一引数関数。引数にはディレクトリ(GDir)を取る。
繰り返すが、K&Rの記述に比べると極めて短くコード構成が可能だ。そしてこの「短さ」はモダンな言語では別に特筆するような短さではないだろう。単に素のC言語には「ユーティリティらしいユーティリティが無かった」と言う事に他ならない。言い換えるとGLibを使えば、21世紀的な「フツーのプログラミング」のレベルまでC言語を「持ち上げる」事が可能なわけだ。
上記の「入門GTK+」及びそのPDF版には、短いながら、他にもファイルアクセス関数、utf-8を扱う関数、タイマーに使える関数、等の例示が載っているので、GLibリファレンスマニュアルでFunctionsを調べる前に、ザーッと目を通してGLibのユーティリティに触れておいた方がいいだろう。

さて最後に良いニュースと悪いニュースがある。
まず、悪いニュースから行ってみよう。
過去、GLibはBoehm GCとコンビを組む事が可能だった。Boehm GCは有名なガベージコレクタライブラリで、C言語をなんとガベージコレクタ有リ〼、の言語にしてしまう。
つまり、かつては、GLibの提供するモダンな抽象データ型+ガベージコレクタ、でC言語をホンマモンのモダンなプログラミング言語にしてしまう、なんつー事が可能だったんだけど、生憎、GTK/GLibのパフォーマンス改善が理由でGLib + Boehm GCのコンビネーションプレイが出来なくなってしまったんだ。
なんとか組み合わせる手がないのか、とか探してたんだけど、結局出来るのは、GLibのソースコードを入手してBoehm GCを組み合わせるように書き換えてコンパイルするしか無い、と言う非常に泥臭く手間がかかる方法しか残されてなかった。
残念だ。
では良いニュース。恐らくC++の影響なんだろうけど、GLibにはg_autoptrと言う、いわゆるスマートポインタがある。これはガベージコレクションと同様に、スマートポインタ変数がスコープを抜けたり、参照先が0になるとメモリが開放され、GCに比べると軽いらしい。
生憎、C言語にはスマートポインタなるモノはないんだけど、一方、gccclang等と言ったコンパイラだとautoptrと言う拡張が入っていて、GLibはそれを利用してスマートポインタをラップしているらしい。
言い換えるとMicrosoft Visual Cだと「使えないだろう」って事なんだけど、それはあまり問題にはならないだろう。MSVCでGLib使おう、ってヤツはいないだろうし(いる?)、WindowsではMinGWを使えば済む話だ。
んで、上の例だと、単に使用したい型をg_autoptrで囲めばいい、って話だ。

g_autoptr(GString) currentdir = g_string_new(argv[1]);
g_autoptr(GDir) dir = g_dir_open(currentdir->str, 0, NULL);

みたいに書けばスマートポインタがメモリの開放まで面倒を見てくれる、と。
実際、まだ使った事がないんで何がどうなるんだか不明なんだが、ひょっとしたらGLib + スマートポインタでLispが書けるかも?とちょっと期待している。
まぁ、Lispを書かないにせよ、スマートポインタ付きGLibで書けばC言語プログラミングは相当ラクになるんじゃないか、と言う希望に満ちた話だ。

おしまい。

※1: ただし、この本の著者は、本が2008年に出版された・・・つまりC99やJIS Cが既に制定されていたにも関わらず、ANSI Cスタイルでコードを書いている。
これは全くと言って望ましくないんで、ここではC99以降で本来望まれてるだろうコードに書き換えてある。
  • Xでシェアする
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

最近の「プログラミング」カテゴリーもっと見る

最近の記事
バックナンバー
人気記事