Running in to an issue when using CTypes

Hello everyone!

I was just playing around with the Ctypes library and ran in to an issue when trying to run my code. I guess what I’m struggling with understanding from Ctypes is how to link my test.c file with my test.ml file. How does Foreign know where to look for the functions it imports?

Thanks,
Hektor

The error I’m getting back is the following:

utop # #use "test1.ml";;
Exception:
Dl.DL_error
 "/home/hektor/.opam/5.1.0/lib/stublibs/dllctypes_foreign_stubs.so: undefined symbol: addition".
Raised at Dl._report_dl_error in file "src/ctypes-foreign/dl.ml.unix", line 44, characters 20-44
Called from Ctypes_foreign_basis.Make.foreign in file "src/ctypes-foreign/ctypes_foreign_basis.ml", line 47, characters 19-47
Re-raised at Ctypes_foreign_basis.Make.foreign in file "src/ctypes-foreign/ctypes_foreign_basis.ml", line 49, characters 50-59
Called from unknown location
Called from Topeval.load_lambda in file "toplevel/byte/topeval.ml", line 89, characters 4-14

I have a folder containing
test1.c
test1.o (built with gcc -c test1.c)
test1.ml

test1.c:

#include <stdio.h>
int addition(int a, int b) {
  return a + b;
}

test1.ml:

open Ctypes
let addition = 
  Foreign.foreign "addition" 
    ~check_errno:true
    (int @-> int @-> returning int)
;;

let _ = print_int (addition 4 5);;

Two options:

  • the functions can be compiled into the same executable as the OCaml code, or
  • you can pass an extra argument to foreign to specify where to look for the functions

If you build a shared library from test1.c:

gcc -shared -o libtest1.so test1.c

and then pass an additional from argument to foreign with details about the shared library

let libtest1 = Dl.dlopen ~flags:[RTLD_GLOBAL; RTLD_NOW] ~filename:"./libtest1.so"

let addition = 
  Foreign.foreign "addition" ~from:libtest1
...

then everything should work out.

1 Like