1(* mosml/src/dynlibs/interface/smlside.sml -- foreign function interface. 2 How to pass SML values to C functions, and how to pass them back. 3 The SML side of things. sestoft@dina.kvl.dk 1998-05-05 *) 4 5(* Load the Dynlib and FileSys structures from the Moscow ML library: *) 6 7app load ["Dynlib", "FileSys"]; 8 9open Dynlib; 10 11(* Obtain a handle pointing to the library defining the C functions: *) 12 13val dlh = dlopen { lib = "libdside.so", 14 flag = RTLD_LAZY, 15 global = false } 16 17(* Define SML functions using this handle. The type ascriptions are 18 necessary for SML type safety: 19 *) 20 21(* Passing and returning base types: unit, int, char, real, string, bool: *) 22 23val fu : unit -> unit = app1 (dlsym dlh "cfu") 24val fi : int -> int = app1 (dlsym dlh "cfi") 25val fc : char -> char = app1 (dlsym dlh "cfc") 26val fr : real -> real = app1 (dlsym dlh "cfr") 27val fs : string -> string = app1 (dlsym dlh "cfs") 28val fb : bool -> bool = app1 (dlsym dlh "cfb") 29 30(* Passing several curried arguments: *) 31 32val fcur : int -> char -> real -> string -> bool -> int = 33 app5 (dlsym dlh "cfcur") 34 35(* Passing a tuple: *) 36 37val ftup : int * char * real -> int = 38 app1 (dlsym dlh "cftup") 39 40(* Passing a record: *) 41 42val frec : { surname : string, givenname : string, age : int } -> bool = 43 app1 (dlsym dlh "cfrec") 44 45(* Passing a constructed value belonging to a datatype: 46 It is advisable to declare the constructors in alphabetical order 47 since Moscow ML 2.00 and later sorts them anyway, and the C side 48 must use the tags (0, 1, ...) of the sorted constructors. 49*) 50 51datatype t = 52 Br of int * t * t 53 | Brs of t list 54 | Lf 55 56val fdat : t -> int = 57 app1 (dlsym dlh "cfdat") 58 59(* Passing an ML function (a closure): *) 60 61val ffun : (int -> real) -> int -> string = 62 app2 (dlsym dlh "cffun"); 63 64(* Returning a tuple *) 65 66val frtup : int -> int * bool = 67 app1 (dlsym dlh "cfrtup"); 68 69(* Returning a record *) 70 71val frrec : int -> { half : int, odd : bool } = 72 app1 (dlsym dlh "cfrrec"); 73 74(* Illustration of heap allocation trickiness *) 75 76val fconcat : string -> string -> string = 77 app2 (dlsym dlh "cfconcat"); 78 79(* Exercising the C functions: *) 80 81val test1 = () = fu (); 82 83val test2 = 5667 = fi 5666; 84 85val test3 = #"T" = fc #"t"; 86 87val test4 = 56.0 = fr 28.0; 88 89val test5 = "TEST NUMBER +1" = fs "Test number +1"; 90 91val test6 = fb false; 92 93val test7 = 85 = fcur 5 #"A" 10.0 "blah" true; 94 95val test8 = 80 = ftup(5, #"A", 10.0); 96 97val test9 = not (frec {surname = "Jensen", givenname = "Karin", age = 28 }); 98 99local 100 val tree = Brs[Lf, 101 Br(12, Br(10, Lf, Lf), Br(20, Lf, Lf)), 102 Brs[Br(15, Lf, Lf)]] 103in 104 105 val test10 = 57 = fdat tree 106end 107 108val test11 = ("Just right" = ffun (fn x => real x + 7.0) 100000); 109 110val test12 = (8, true) = frtup 17; 111 112val test13 = {half = 8, odd = true} = frrec 17; 113 114val test14 = "abcdef" = fconcat "abc" "def"; 115 116val _ = quit(); 117