Next: , Up: Writing Dynamic Modules   [Contents][Index]


E.8.1 モジュールの初期化コード

ヘッダーファイルemacs-module.hのインクルードとGPL互換性シンボル(GPL compatibility symbol)によりモジュールの記述を始めましょう:

#include <emacs-module.h>

int plugin_is_GPL_compatible;

Emacsインストールの一部としてシステムのインクルードツリーにemacs-module.hファイルがインストールされます。かわりにEmacsのソースツリー内で見つけることもできます。

次にモジュール用の初期化関数を記述します。

Function: int emacs_module_init (struct emacs_runtime *runtime)

Emacsはモジュールをロードする際にこの関数を呼び出す。モジュールがemacs_module_initという名前の関数をエクスポートしていなければモジュールはエラーをシグナルする。この初期化関数は初期化成功時には0、それ以外は非0をリターンすること。後者の場合にはEmacsはエラーをシグナルして、モジュールのロードは失敗する。初期化中にユーザーがC-gを押下すると、Emacsは初期化関数のリターン値を無視してquitする(Quittingを参照)(必要なら初期化関数内でユーザーのquitをcatchできる。should_quitを参照)。

引数runtimeは2つのパブリックなフィールドを含むCのstructへのポインター、sizeはその構造体のバイトサイズ、get_environmentはEmacsの環境オブジェクトとそのインターフェースにモジュール初期化関数をアクセス可能にする関数へのポインターを提供する。

初期化関数はモジュールに必要な初期化は何であれすべて行うこと。さらに以下のタスクを行うことができる:

互換性の検証

モジュールにコンパイルされたruntime構造体のsizeメンバーの値を比較することにより、モジュールをロードするEmacs実行可能形式がモジュールと互換性があるか検証できる。

int
emacs_module_init (struct emacs_runtime *ert)
{
  if (ert->size < sizeof (*ert))
    return 1;
}

モジュールに渡されたruntimeオブジェクトのsizeが期待する値より小さければ、ロードしようとしているモジュールがEmacsの新しい(最近の)バージョン向けにコンパイルされていることを意味する(そのモジュールはEmacsのバイナリーとは非互換かもしれない)。

さらにモジュールは期待しているモジュールAPIの互換性も検証できる。以下の例では上述のemacs_module_init関数の一部であることを仮定している:

  emacs_env *env = ert->get_environment (ert);
  if (env->size < sizeof (*env))
    return 2;

これはAPI環境(environment)へのポインターの取得用に構造体runtime (sizeフィールドに構造体のバイトサイズも保有するCstruct )で提供されるポインターを使用してget_environment関数を呼び出す。

最後にEmacsから渡された環境のサイズと既知のサイズを比較することによって、以下のように古いバージョンのEmacsで動作するモジュールを記述できる:

  emacs_env *env = ert->get_environment (ert);
  if (env->size >= sizeof (struct emacs_env_26))
    emacs_version = 26;  /* Emacs 26 or later.  */
  else if (env->size >= sizeof (struct emacs_env_25))
    emacs_version = 25;
  else
    return 2; /* Unknown or unsupported version.  */

新しいバージョンのEmacsではメンバーを環境に常に追加して削除は決して行わないので、新たなEmacsのリリースではサイズは増加するだけであることにより機能する。与えられたバージョンのEmacsにたいして、そのバージョンに存在するモジュールAPIは新しいバージョンのものと等しいので、その部分だけを使用できる。

モジュールが処理全体を初期化関数内で行い、Lispオブジェクトにアクセスしたり環境構造体を通じてアクセス可能なEmacs関数を使用することがない場合を除いて、モジュールの互換性検証を常に行うことを推奨する。

Lispシンボルへのモジュール関数のバインド

これはLispコードが名前で呼び出せるようにモジュール関数に名前を与える。これを行う方法については以下のModule Functionsで説明する。