user3240588
user3240588

Reputation: 1252

Load and use symbols from shared library with ctypes in OCaml toploop

I'm trying to use functions from a small self-contained fortran library from OCaml. I can compile the library with gfortran -shared mvndst.f -o sharedlib. Invoking nm sharedlib shows a list of symbols, e.g. ... T _mvndfn_.

After reading the ctypes tutorial example https://github.com/ocamllabs/ocaml-ctypes/wiki/ctypes-tutorial I tried to do something like let mvndfn = foreign "mvndfn" (ptr double @-> returning float). The symbol was not found. Maybe not surprising since I didn't tell it where to look - but I don't know how.

Can this work at all? How to I tell the toploop to look for this shared library? Does it matter that it's Fortran not C? How do I finally compile and link a program if it works in the toploop?

(This is on OS X)

Upvotes: 0

Views: 418

Answers (1)

Étienne Millon
Étienne Millon

Reputation: 3028

Foreign.foreign takes an optional argument ?from that is a value of type Dl.library (you can see it in the docs). You can get one of those with Dl.dlopen (dynamic loading is a complicated topic but you often want [RTLD_LAZY]).

Here is an example using libpng:

# let libpng = Dl.dlopen ~flags:[Dl.RTLD_LAZY] ~filename:"/usr/lib/x86_64-linux-gnu/libpng16.so.16";;
val libpng : Dl.library = <abstr>
# open Foreign;;
# open Ctypes_static;;
# let f = foreign ~from:libpng "png_get_libpng_ver" (ptr void @-> returning (ptr char));;
val f : unit Ctypes_static.ptr -> char Ctypes_static.ptr = <fun>
# let p = f Ctypes.null;;
val p : char Ctypes_static.ptr = (char*) 0x7f9d5220e64e
# Ctypes.string_from_ptr ~length:6  p;;
- : string = "1.6.26"

Upvotes: 5

Related Questions