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