Hi David,
I'm about to start generating code that makes calls to C via the low-level FFI. I was planning to use a form where parameters that provide return values are temporary vols created by alloc, as shown in the example SML code below (as suggested in the C interface documentation). However, it appears that the high-level FFI implementation doesn't do things this way - it uses call_sym_and_convert. Is that more efficient and should I be looking at that?

Using the alloc form works when a parameter is both and input and an output: in the example C code below, the second parameter `pos` is an in-out. I notice that call_sym_and_convert doesn't have an InOut constructor for Union.directedArg. This appears to be a problem for ML types that are not a vol (i.e. not passed by reference in the C FFI) such as int. Is there a way around this?

Thanks,
Phil


/* -- C -- */

#include <string.h>

#define TRUE  (0 == 0)
#define FALSE (0 != 0)

/* get_next (s, pos, c) copies the character at offset pos in string s
 * to c, increments pos and returns TRUE, if pos is a valid index into s.
 * If pos is not a valid index, the function returns FALSE without
 * incrementing pos or writing to c.
 */
int get_next (const char *s,  /* in     */
              int *pos,       /* in out */
              char *c)        /*    out */
{
  int len = strlen (s);
  if (0 <= *pos && *pos < len) {
    *c = s[*pos];
    (*pos)++;
    return TRUE;
  }
  else {
    return FALSE;
  }
}


(* -- SML -- *)

open CInterface

val lib = load_lib "testlib.so.1"

val (fromCbool, toCbool, Cbool) = breakConversion BOOL
val Cstring = Cpointer Cchar

val get_next =
  fn (in1, in2) =>
    let
      val sym = load_sym lib "get_next"
      val tmp2 = alloc 1 Cint
      val tmp3 = alloc 1 Cchar
      val () = assign Cint tmp2 (toCint in2)
      val args = [
        (Cstring,        toCstring in1),
        (Cpointer Cint,  address tmp2),
        (Cpointer Cchar, address tmp3)
      ]
      val res = fromCbool (call_sym sym args Cbool)
      val out2 = fromCint tmp2
      val out3 = fromCchar tmp3
    in
      (res, out2, out3)
    end;

get_next ("hello", 0);
get_next ("hello", 1);
get_next ("hello", 2);
get_next ("hello", 3);
get_next ("hello", 4);
get_next ("hello", 5);


(* Poly/ML output *)

...
val it = (true, 1, #"h"): bool * int * char
val it = (true, 2, #"e"): bool * int * char
val it = (true, 3, #"l"): bool * int * char
val it = (true, 4, #"l"): bool * int * char
val it = (true, 5, #"o"): bool * int * char
val it = (false, 5, #"\^@"): bool * int * char


_______________________________________________
polyml mailing list
polyml@inf.ed.ac.uk
http://lists.inf.ed.ac.uk/mailman/listinfo/polyml

Reply via email to