SML#がサポートする相互運用型

外部関数とデータを受け渡しできる型を相互運用型と呼ぶことにする.SML#では現在以下相互運用型の集合をサポートしている.

ity ::= scalar | real | float | string | ity * ... * ity | ity array

さらに,高階関数もサポートしている.SML#で外部関数と相互運用可能な型は以下の文法で与えられる.

ty  ::= ity | ty -> ty

SML#コンパイラは,高階関数が引数に指定されると,Ohori&KatoPOPL93 に示されたアルゴリズムを用いて,相互運用型を受け渡す関数の合成に自動的に分解する.この過程は完全に自動的に行われる.したがって,この機能を使用するプログラマは,SML#で定義した関数をその型とともに引数として与えるだけでよい.

スカラー値(scalar)

(計算機の自然な,現在の多くのプラットフォームでは32ビットの)1語長のスカラー値(ポインターではない)を表現する型は一般にすべて相互運用型として扱うことができる.一般的なプラットフォームでは,Cのlongintchar型などを含む.SML#では,int型やchar型,引数を含まないboolのようなデータ型に対応する.

浮動小数点データ(real, float)

計算機によって直接サポートされている倍精度浮動小数点表現を表現する型は相互運用型である.

SML#ではreal型は64ビット長の浮動小数点表現であり,一般的なプラットフォームでは,Cのdouble型に相当する.

これに加え,SML#では1語長の浮動小数点データ型floatを提供している.一般的なプラットフォームでは,Cの''float型"に相当する.

文字列データ(string)

Cのchar*型のデータは相互運用型として扱うことができます.SML#のstring型データに対応すます.

配列(ity array)

要素の型が相互運用型であるSML#の配列型は相互運用型であり,Cの配列型に対応する.例えば,SML#の

 A : real array

はCの

double A[]
double *A

のような宣言に対応する.

タプルとレコード(ity * ... * ity)

相互運用型をメンバーとするSML#のタプル型は相互運用型であり,Cの構造体へのポインター型に対応する.

SML#ではレコードは,ラベルの辞書式順序によってソートされたタプル型と同一の内部表現をとっており,この約束のもとに,相互運用型として扱うことができる.

例えば,Cで

struct S {int x; char y;};
int f(struct S* s);

と宣言された関数は,以下のように宣言して使用することができる.

val f = DynamicLink.dlsym(libFoo, "f") : _import (int * char) -> int;

浮動小数点データを含むの構造体も同様に扱うことが可能である.例えば,

struct S {double x; double y;};
int f(struct S* s);

と宣言された関数は,以下のように宣言して使用することができる.

val f = DynamicLink.dlsym(libFoo, "f") : _import (real * real) -> int;

SML#コンパイラは,アーキテクチャ依存のアラインメント等を行っている.詳しくはSML#020の制限を参照.

トップレベルの関数型(ity -> ty)

引数および返り値とも相互運用型であるSML#の関数型は,トップレベルの相互運用型として扱うことができる.配列やタプル等の要素として扱うことはできない.この機能を利用して,SML#の関数をコールバック関数としてCに渡すことができる.

Last modified:2007/03/30 03:04:49
Keyword(s):
References:[外部関数束縛] [_ffiapply特殊構文]