_ffiapply特殊構文

Cで定義された型依存の振る舞いをする関数などをSML#から呼び出すための低レベルな構文である.以下の文法を持つ.

_ffiapply <exp> (<arg>, ..., <arg>) : <ty>

ここで,

  • <exp> はunit ptr型のCの関数ポインタ式,
  • <arg> はCに渡す引数の指定,
  • <ty> は返り値の型である.

各引数は以下の文法で指定する.

式と型の指定
<arg> ::= <exp> : <ty> | _sizeof(<ty>)

ここで,

  • <exp> : <ty>はC関数に渡す式とその型の指定
  • _sizeof(<ty>) はSML#が管理する型<ty>の表現サイズ情報の参照である.この特殊構文は,コンパイラによって型のサイズを表す式に自動的に置き換えれる.
  • <ty> は任意の相互運用型を指定できる.

例えば,Cのライブラリ関数qsort(3)は以下のように呼び出すことができる.

 val libc = DynamicLink.dlopen "/lib/libc.so.6"
 val c_qsort = DynamicLink.dlsym (libc, "qsort")
 fun qsort (a, f) =
     _ffiapply c_qsort (a : 'a array,
                        Array.length a : int,
                        _sizeof('a),
                        f : ('a ptr, 'a ptr) -> int) : unit

関数の引数は配列aと比較を行うコールバック関数である.関数本体で,C関数に,配列の要素数と配列の要素のサイズを渡している.これによって,qsortは,ポインター操作による効率よいinplaceクイックソートを行う.この定義によって以下の型の関数が生成される.

val qsort : ['a. 'a array * ('a ptr * 'a ptr -> int) -> unut]

注意

この構文を用いたC関数の呼び出しの定義は,SML#の型主導コンパイルの結果のC関数呼び出し式をコーディングしていることに相当する.この式を書くプログラマは,これら引数の数,その順序および型が実際のC関数の仕様と一致していることを確認する必用がある.

その一致が保証されれば,qsortのようなポインタを操作する低レベルの関数も,SML#からデータ変換などのオーバヘッド無に,しかも型安全に直接呼び出すことができる.

Last modified:2007/03/25 11:32:54
Keyword(s):
References:[外部関数束縛] [_import特殊構文]