SML# - Language/FFI/Types Diff

  • Added parts are displayed like this.
  • Deleted parts are displayed like this.

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

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

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

ty  ::= ity | ty -> ty

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


!スカラー値(scalar)
(計算機の自然な,現在の多くのプラットフォームでは32ビットの)1語長の
スカラー値(ポインターではない)を表現する型は一般にすべて
相互運用型として扱うことができる.
一般的なプラットフォームでは,Cの
''long''型
''int''型
''char''型
などを含む.
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の制限|Language/FFI/Restrictions]]を参照.

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