SML# - Resources/ProgrammingExamples/Struct Diff

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

32ビット整数(int型;long型)や64ビット浮動小数点データ(real型;
double 型)などの原子データ以外に,それらを含む構造体も受け渡すことが
できる.
ただし,構造体の場合,アラインメント(境界制約)は処理系依存である.
そこで,SML#0.20版では,もっとも条件の強い以下のアラインメント処理を行っている.
* realは8バイト境界に配置(必用に応じてバディングデータを挿入)
* intは4バイト境界に配置
* 1ワードへの文字や32ビット未満の整数のパックはサポートしない.
このアラインメント条件を満たすCの構造体へのポインタは,SML#の組み型に対応しており,
受け渡すことができる.
以下は構造体を受け取るCの関数例である.
  #include <stdio.h>
  typedef struct {double x; int y;} foo;
  typedef struct {int y; int padding; double x;} bar;
  int f (foo *a)
  {
    printf ("%g\n", (*a).x);
    printf ("%d\n", (*a).y);
    return (a->y + 1);
  }
  int g (bar *a)
  {
    printf ("%g\n", a->x);
    printf ("%d\n", a->y);
    return (a->y + 1);
  }
これら関数は,SML#から以下のような宣言を通じて使用することが出来る.
  val a = DynamicLink.dlopen "./struct.so";
  val fName = DynamicLink.dlsym(a, "f");
  val gName = DynamicLink.dlsym(a, "g");
  val f = fName : _import (real*int) -> int;
  val g = gName : _import (int*real) -> int;
  f (3.14,99);
  g (99,3.14);
SML#は以下のような結果を表示する.
  # use "struct.sml";
  val a = 0x083d8550 : unit ptr
  val fName = 0x45154724 : unit ptr
  val gName = 0x45154761 : unit ptr
  val f = fn : real * int  -> int
  val g = fn : int * real  -> int
  3.14
  99
  val it = 100 : int
  3.14
  99
  val it = 100 : int
  #

なお,将来は,SML#のシステム生成時に,アラインメント制約を,指定され
た現在のアーキテクチャでのCコンパイラに合わせることを計画している.