SML# - Resources/ProgrammingExamples/Struct Diff

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

In addition to integers and doubles, you can pass a tuple as a
struct data to C.
A care must be taken, however, since ''data alignment'' in
C struct is implementation dependent.
To deal with this problem, the cureent SML#  0.20 release
adotp the following most strict policy on data alignment in tuple.
* a real data is on 8 byte boundary (padding is inserted if needed)
* an int data is on 4 byte boundary
* a packed data of less than 1 word (such as char) is not supported
Any tuple satisfying these alignment condition can be passed to C as
a pointer to the corresponding struct data.

The following is an example C function that takes a struct pointer.
  #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);
  }
These functions can be called from SML# as follwos.
  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# prints the following result:
  # 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
  #

In future, we plan to implement an architecture dependent configuration of alignment policy.