7 val dlopen
: string * mode
-> hndl
8 val dlsym
: hndl
* string -> fptr
9 val dlclose
: hndl
-> unit
15 structure DynLink
:> DYN_LINK
=
17 type hndl
= MLton
.Pointer
.t
18 type mode
= Word32
.word
19 type fptr
= MLton
.Pointer
.t
21 (* These symbols come from a system libray
, so the default import scope
22 * of external is correct
.
25 _import
"dlopen" : string * mode
-> hndl
;
27 _import
"dlerror": unit
-> MLton
.Pointer
.t
;
29 _import
"dlsym" : hndl
* string -> fptr
;
31 _import
"dlclose" : hndl
-> Int32
.int;
33 val RTLD_LAZY
= 0wx00001 (* Lazy function call binding
. *)
34 val RTLD_NOW
= 0wx00002 (* Immediate function call binding
. *)
36 val dlerror
= fn () =>
40 if addr
= MLton
.Pointer
.null
43 fun loop (index
, cs
) =
45 val w
= MLton
.Pointer
.getWord8 (addr
, index
)
46 val c
= Byte
.byteToChar w
49 then SOME (implode (rev cs
))
50 else loop (index
+ 1, c
::cs
)
57 val dlopen
= fn (filename
, mode
) =>
59 val filename
= filename ^
"\000"
60 val hndl
= dlopen (filename
, mode
)
62 if hndl
= MLton
.Pointer
.null
63 then raise Fail (case dlerror () of
69 val dlsym
= fn (hndl
, symbol
) =>
71 val symbol
= symbol ^
"\000"
72 val fptr
= dlsym (hndl
, symbol
)
76 | SOME s
=> raise Fail s
79 val dlclose
= fn hndl
=>
80 if MLton
.Platform
.OS
.host
= MLton
.Platform
.OS
.Darwin
81 then () (* Darwin reports the following error message
if you
82 * try to close a dynamic library
.
83 * "dynamic libraries cannot be closed"
84 * So
, we disable dlclose on Darwin
.
88 val res
= dlclose hndl
92 else raise Fail (case dlerror () of
100 open MLton
.Platform
.OS
103 Cygwin
=> "cygwin1.dll"
104 | Darwin
=> "libm.dylib"
108 val hndl
= DynLink
.dlopen (dll
, DynLink
.RTLD_LAZY
)
111 val double_to_double
=
112 _import
* : DynLink
.fptr
-> real -> real;
113 val cos_fptr
= DynLink
.dlsym (hndl
, "cos")
115 val cos
= double_to_double cos_fptr
118 val _
= print (concat
[" Math.cos(2.0) = ", Real.toString (Math
.cos
2.0), "\n",
119 "libm.so::cos(2.0) = ", Real.toString (cos
2.0), "\n"])
121 val _
= DynLink
.dlclose hndl