[ocaml-ctypes] Bind a function with a type external to the library

Jeremy Yallop yallop at gmail.com
Tue Jan 27 12:45:26 GMT 2015


On 21 January 2015 at 22:07, Jacques-Pascal Deplaix
<jp.deplaix at gmail.com> wrote:
> I'm trying to bind libmemphis with ctypes and I encounter some problems with
> one function in particular:
> https://github.com/LamaUrbain/ocaml-memphis/blob/master/src/memphis_renderer.ml#L55
>
> The function takes a cairo_t in C but in OCaml I would like to use
> Cairo.context.
> So I tried by using Obj.magic in the overloading just below (in the code
> linked above) but when I try to use the function it segfaults in some random
> cairo function (memphis_renderer_draw_tile is called before and seems to
> work).
>
> Is there an other way to use an OCaml type (Cairo.context) instead of the
> abstract C type or the problem might comes from somewhere else ?

If the cairo_t value isn't used abstractly inside libmemphis then
passing an OCaml value instead of a cairo_t won't work.  You need to
somehow extract the address of the underlying C object from the
abstract Cairo representation and then pass that address to
libmemphis.  A quick look at the Cairo source suggests that something
along the following lines might work, but I haven't compiled or tested
it:

  /* C stub for turning a Cairo.t into a ctypes-compatible address */
  #include "ml_cairo.h"
  #include <caml/mlvalues.h>
  #include <caml/alloc.h>
  #include <stdint.h>

  value cairo_address(value v)
  {
     return caml_copy_native_int((intptr_t)cairo_t_val(v));
  }


  (* ML binding for the C stub *)
  external cairo_raw_address : Cairo.t -> nativeint =
    "cairo_address"

  let ctypes_ptr_of_cairo_t : Cairo.t -> unit Ctypes.ptr =
    fun c -> Ctypes.ptr_of_raw_address (cairo_raw_address c)


More information about the Ctypes mailing list