PerlQt移植ヒストリ(第10回)

『あることを研究する者にとって、不具合は強烈な動機づけとなる』
(PerlQt移植奮闘記よりw)

起動時の処理

"use Qt;"により何が起こるのかを研究した。

  1. Perlのルールに従ってQt.pmがロードされ、実行される。
  2. Qt.pmの"bootstrap Qt $VERSION;"により、Qt.soがロードされ、"pigboot.c/XS(boot_Qt)"が呼び出されることにより以下の処理が実行される。
  3. "pigsymbol.c/pig_symbol_exchange()"が実行され、名前に対する関数や型のポインターのテーブル(エクスポートテーブル)によって、同じ名前に対する関数や型のポインターを保存するメモリーのテーブル(インポートテーブル)が初期化される。
    下記 7. の"pigclassinfo.c/pig_load_classinfo()"はインライン関数として定義されたラッパーであり、関数ポインタを使用して間接的に実体のスタティック関数を呼び出しているが、その関数ポインタはここで初期化される。
    ただし、なぜラッパー関数による間接的呼び出しをわざわざ行っているのかは現時点で不明である。
  4. "%main::INC"に"Qt/app.pm"、"Qt/signals.pm"、"Qt/slots.pm"をキーとして"pigboot.c"(ダミーの値)を定義することで、各モジュールを登録(つまり、"Qt::app"、"Qt::signals"、"Qt::slots"をロード済みと)する。
  5. "pigemit.c/XS(PIG_Qt__signals_import)"を"Qt::signals::import"サブルーチンとして定義し、スクリプトで"use Qt::signals '', ...;"(※1)と記述することにより、スクリプト上の新しいシグナルを生成できるようにする。
  6. "pigemit.c/XS(PIG_Qt__slots_import)"を"Qt::slots::import"サブルーチンとして定義し、スクリプトで"use Qt::slots '', ...;"(※1)と記述することにより、スクリプト上の新しいスロットを設置できるようにする。
  7. "pigclassinfo.c/pig_load_classinfo()"が実行され、Perlのハッシュを利用して、C++上のクラス名に対する管理テーブルのポインターC++上のクラス名に対するPerl上のパッケージ名、及びその逆参照のテーブルを作成する。
    また、各クラスで定義されている定数(整数、文字列、オブジェクト)と自動ローダーを、対応するPerl上のパッケージに定義する。
  8. "pigconstant.c/pig_load_constants()"が実行され、"Qt"パッケージに整数、文字列、オブジェクトを定義する。
    今のところは定義内容がない。
  9. "pigboot.c/XS(PIG_app_import)"を"Qt::import"サブルーチンとして定義し、スクリプトで"use Qt;"(*1)と記述することにより、現在のパッケージにQtアプリケーションクラスのインスタンスへの参照を"$app"変数に設定する。

つづく…かも。

*1:Perlでは、"use <パッケージ名>;"により、暗黙的に"<パッケージ名>::import"が呼び出される仕様がある。