FFI utility library

This library provides utility functions to support writing codes using SML# FFI version 0.20.

In its final form we would like to complete in 2008, SML# shall provide interoperable memory management that is more uniform and transparent to the user.

API
API document

This library is loaded in the default prelude.

If you use other prelude which does not load the FFI utility library, you can load it as follows.

# use "FFI.sml";

External memory utilities.

A pointer to a memory block allocated outside of SML# heap is not compatible with value of SML# types, such as string, Word8Vector.vector. Therefore, as described in foreign function binding, there are two restrictions in exchanging a pointer to memory block between SML# and external libraries.

  • A pointer to a memory block allocated outside of SML# heap should not be imported to SML#.
  • An external library should not hold a pointer to a memory block allocated in SML# heap beyond an invocation of an external function.

UnmanagedMemory and UnmanagedString structures provide utility functions

import a pointer to external memory to SML#.

A pointer to a memory block allocated outside of SML# heap is not compatible with value of SML# types, such as string, Word8Vector.vector.

If you want to access the contents of external memory block as normal SML values, you can use this library to copy the contents of a external memory block into a block that is newly allocated in SML# heap.

char* gs = "abc";
char* f(){ return gs; }
val libfoo = DynamicLink.dlopen "libfoo";
val fptr = DynamicLink.dlsym (libfoo, "f");
val f = fptr : _import () -> UnmanagedString.unmanagedString;
val ums = f ();
val s = UnmanagedString.import ums;

s can be used as a string as usual.

export a pointer to a SML# heap block to external library.

The FFI utility library provides functions to allocate a block in external memory and access/update the contents of it. And a function to copy the contents of SML# string into an external memory block is provided also. This unmanaged pointer can be passed to external library.

Because the memory block is not managed by GC, you have to release it by calling 'UnmagedMemory.release'.

char* gs;
int f(char* s){ gs = s; return 0; }
val libfoo = DynamicLink.dlopen "libfoo";
val fptr = DynamicLink.dlsym (libfoo, "f");
val f = fptr : _import (UnmanagedString.unmanagedString) -> int;
val s = "abc";
val ums = UnmanagedString.export s;
val _ = f ums;
val _ = UnmanagedString.release ums;
Last modified:2007/03/28 13:01:16
Keyword(s):
References:[DynamicLink structure] [Restrictions in 0.20 Release] [Library]