Hi,

Although Poly/ML has nice interface for calling C functions, it only
supports dynamic linking. <http://www.polyml.org/docs/CInterface.html>

This is not pleasant if you want to distribute a program as a simple
stand-alone executable. (setting the library path might be crumsy for
the user)

A solution would be 'linking statically but loading dynamically.'
Actually, dlopen seems to support this if the filename argument is NULL.

The following experiment (on Ubuntu 13.04 x86_64) seems to have
succeeded, but needs a little modification to Poly/ML.
How do you think? Any chance for Poly/ML to incorporate something
similar?

Best regards,
-- KOBAYASHI, Tomoyas

===== patch =====

--- foreign.cpp.orig    2014-02-15 00:29:32.334802335 +0900
+++ foreign.cpp 2014-02-15 00:35:58.362818505 +0900
@@ -742,7 +742,7 @@
     return res;

 #else  /* UNIX version */
-    void *lib = dlopen(name,DLOPENFLAGS);
+    void *lib = dlopen(*name == 0 ? NULL : name,DLOPENFLAGS);
     if (!lib)
     {
         char buf[256];

===== experiment session =====

$ cat difference.c
int difference (int x, int y) {
     return x > y ? x - y : y - x;
}
$ gcc -c difference.c -fPIC -o difference.o
$ cat diff.sml
local open CInterface in

fun diff (n, m) =
  let
    val lib = load_lib ""
    val sym = load_sym lib "difference"
    val diff' = call2 sym (INT, INT) INT
  in
    diff' (n, m)
  end

fun main () =
  print (Int.toString (diff (13, 50)) ^ "\n");

end
$ poly
Poly/ML 5.5.2 Testing
> use "diff.sml";
val diff = fn: int * int -> int
val main = fn: unit -> unit
val it = (): unit
> PolyML.export("diff.o", main);
val it = (): unit
>
$ gcc -L ~/poly/lib -rdynamic diff.o difference.o -lpolymain -lpolyml
-lstdc++ -lm -ldl -lpthread -lgmp
$ ./a.out
37
$

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

Reply via email to