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


E.8.3 Lisp・モジュール間の値変換

非常に少数の例外を除くほとんどのモジュールでは、モジュールを呼び出すLispプログラムとの間でモジュール関数への引数やリターン値の受け渡しでデータのやり取りが必要になります。この目的にたいしてモジュールAPIemacs_valueタイプを提供しています。これはAPIを通じたやり取りにおいてEmacsのLispオブジェクトを表現するタイプであり、EmacsのCプリミティブ(Writing Emacs Primitivesを参照)で使用されるLisp_Objectタイプと機能的には等価です。このセクションではLispの基本データ型に対応するemacs_valueオブジェクトの作成を可能とするモジュールAPIの部分と、Lispオブジェクトに対応するemacs_valueオブジェクト内のCデータへのアクセス方法について説明します。

以下で説明するすべての関数は、実際にはすべてのモジュール関数が受け取る環境へのポインターを介して提供される関数ポインター(function pointers)です。したがってモジュールのコードでは以下のように環境ポインターを通じてこれらの関数を呼び出す必要があります:

emacs_env *env;  /* the environment pointer */
env->some_function (arguments…);

emacs_envポインターは通常はモジュール関数の1つ目の引数、モジュール初期化関数内で環境が必要な場合にはget_environmentの呼び出しから取得できます。

以下で説明するもののほとんどはEmacs 25で利用可能になった関数であり、Emacs 25はダイナミックモジュールを最初にサポートした最初のEmacsリリースです。それ以降のリリースで利用可能になったいくつかの関数につていは、それらをサポートする最初のEmacsバージョンを付記します。

以下のAPI関数はemacs_valueオブジェクトから種々のCデータ型を抽出します。これらすべては引数のemacs_valueオブジェクトがその関数の期待するタイプでなければ、エラーコンディションwrong-type-argumentをraiseします(Type Predicatesを参照)。Emacsモジュール内でエラーをシグナルする方法、およびEmacsにエラーが報告される前にモジュール内部でエラーコンディションをcatchする方法の詳細はModule Nonlocalを参照してください。emacs_valueのタイプ取得にはAPI関数type_ofを使用できます(type_ofを参照)。

Function: intmax_t extract_integer (emacs_env *env, emacs_value arg)

この関数はargで指定されたLisp整数の値をリターンする。リターン値のCデータ型intmax_tはCコンパイラーがサポートする最大の整数型であり、一般的にはlong long

Function: double extract_float (emacs_env *env, emacs_value arg)

この関数はargで指定されたLisp浮動小数の値をCのdouble値としてリターンする。

Function: bool copy_string_contents (emacs_env *env, emacs_value arg, char *buf, ptrdiff_t *len)

これはargで指定されたLisp文字列をUTF-8にエンコードしたテキストをbufが指すchar配列に格納する。bufは少なくとも終端のnullバイトを含む*lenバイトを保持するために十分なスペースをもつこと。引数lenNULLポインターであってはならない。この関数の呼び出し時にはbufのバイトサイズを指定する値を指していること。

*lenで指定されたバッファーサイズが文字列のテキストを保持するために十分大きければ、関数は終端のnullバイト含む実際にコピーされる*lenバイトをbufにコピーしてtrueをリターンする。バッファーが小さすぎる場合には、関数はエラーコンディションargs-out-of-rangeをraiseするとともに、必要なバイト数を*lenに格納してfalseをリターンする。保留中のエラーコンディションのハンドル方法はModule Nonlocalを参照のこと。

引数bufNULLポインターでもよく、この場合には関数はargのコンテンツの格納に必要なバイト数を*lenに格納してtrueをリターンする。これは特定の文字列を格納するために必要なbufサイズを決定する手段となり得る。1回目はbufNULLcopy_string_contentsを呼び出して、関数により*lenに格納されたバイト数の保持に十分なメモリーを割り当ててから、実際にテキストのコピーを行うために非NULLbufで関数を再び呼び出す。

Function: emacs_value vec_get (emacs_env *env, emacs_value vector, ptrdiff_t index)

この関数はvectorindexの要素をリターンする。ベクターの最初の要素のindexは0。indexの値が無効ならこの関数はエラーコンディションargs-out-of-rangeをraiseする。関数のリターン値からCデータを抽出するためには、ベクターの当該要素に格納されたLispデータタイプに応じて、ここで説明している他の抽出関数を使用すればよい。

Function: ptrdiff_t vec_size (emacs_env *env, emacs_value vector)

この関数はvector内の要素数をリターンする。

Function: void vec_set (emacs_env *env, emacs_value vector, ptrdiff_t index, emacs_value value)

この関数はvectorのインデックスindexの要素にvalueを格納する。indexの値が無効ならこの関数はエラーコンディションargs-out-of-rangeをraiseする。

以下はCの基本データ型からemacs_valueオブジェクトを作成するAPI関数です。これらはすべて作成したemacs_valueオブジェクトをリターンします。

Function: emacs_value make_integer (emacs_env *env, intmax_t n)

この関数は引数n (整数)を受け取り対応するemacs_valueオブジェクトをリターンする。nの値をEmacs整数で表現できない、すなわちmost-negative-fixnummost-positive-fixnumの範囲外(Integer Basicsを参照)ならエラーコンディションoverflow-errorをraiseする。

Function: emacs_value make_float (emacs_env *env, double d)

この関数はdoubleの引数dを受け取り対応するEmacs浮動小数点値をリターンする。

Function: emacs_value make_string (emacs_env *env, const char *str, ptrdiff_t strlen)

この関数はstrが指す、終端のnullバイトを含まないバイト長がstrlenであるようなCテキスト文字列からEmacs文字列を作成する。strの元文字列はASCII文字列かUTF-8にエンコードされた非ASCII文字列が可能であり、文字列には埋め込みのnullバイトを含むことができ、str[strlen]にあるnullバイトで終端される必要はない。strlenが負、またはEmacs文字列の最大長を超過する場合には、この関数はエラーコンディションoverflow-errorをraiseする。

このAPIはたとえばconslistによるリスト作成(Building Listsを参照)、carcdrによるリストメンバーの抽出(List Elementsを参照)、vectorによるベクター作成(Vector Functionsを参照)等のようなLispデータ構造を操作する関数は提供しません。これらにたいしてはたいおう するLisp関数を呼び出すために、次のサブセクションで説明するinternfuncallを使用します。

emacs_valueオブジェクトのライフタイムはかなり短いのが普通です。このライフタイムはオブジェクトの作成に使用されたemacs_envポインターがスコープ外になると終了します。emacs_valueが望む間は行き続けるようなグローバル参照(global references)を作成を要する場合もあるかもしれません。そのようなオブジェクトの管理には以下の2つの関数を使用します。

Function: emacs_value make_global_ref (emacs_env *env, emacs_value value)

この関数はvalueのグローバル参照をリターンする。

Function: void free_global_ref (emacs_env *env, emacs_value global_value)

この関数は以前にmake_global_refで作成したglobal_valueを解放する。global_valueはこの呼び出し後は無効になる。モジュールのコードではmake_global_refと対応するfree_global_refの呼び出しそれぞれをペアーとすること。

後でモジュール関数に渡す必要があるCデータ構造体を追跡するための代替え手段はユーザーポインター(user pointer)オブジェクトの作成です。ユーザーポインター(またはuser-ptr )はCポインターをカプセル化したLispオブジェクトであり、関連付けられたファイナライザー(オブジェクトがガーベージコレクトされる際に呼び出される。Garbage Collectionを参照)をもつことができます。モジュールAPIuser-ptrオブジェクトの作成やアクセスを行う関数を提供します。これらの関数はuser-ptrオブジェクトを表現しないemacs_valueで呼び出されるとエラーコンディションwrong-type-argumentをraiseします。

Function: emacs_value make_user_ptr (emacs_env *env, emacs_finalizer fin, void *ptr)

この関数はCポインターptrをラップしたuser-ptrオブジェクトを作成してリターンする。ファイナライザー関数finNULL (ファイナライザーなし)、または以下のシグネチャをもつ関数のいずれか:

typedef void (*emacs_finalizer) (void *ptr);

finNULLポインターでなければ、user-ptrオブジェクトがガーベージコレクトされる際にptrを引数として呼び出される。Emacsの応答性を維持するためにGCは短時間で終了しなければならないので、ファイナライザーでは高価なコードの実行は行ってはならない。

Function: void *get_user_ptr (emacs_env *env, emacs_value val)

この関数はvalで表されるLispオブジェクトからCポインターを抽出する。

Function: void set_user_ptr (emacs_env *env, emacs_value value, void *ptr)

この関数はvalueで表されるuser-ptrオブジェクトに埋め込まれたCポインターにptrをセットする。

Function: emacs_finalizer get_user_finalizer (emacs_env *env, emacs_value val)

この関数はvalで表されるuser-ptrオブジェクトのファイナライザー、ファイナライザーがなければNULLをリターンする。

Function: void set_user_finalizer (emacs_env *env, emacs_value val, emacs_finalizer fin)

この関数はvalで表されるuser-ptrオブジェクトのファイナライザーをfinに変更する。finNULLならuser-ptrオブジェクトのファイナライザーはなくなる。


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