Link

Opaque Types

ppx_cstubs provides various helper to deal with values whose types differ from platform to platform or that are kept opaque.

Abstract

let%c myabstract = abstract "foo"

The statement above will be translated to something along the following lines - with size and alignment determined automatically:

type myabstract
let myabstract : myabstract Ctypes.abstract Ctypes.typ = 
   Ctypes.abstract ~size ~alignment ~name:"foo"

abstract is most suitable for structs and unions, whose members are private or don’t need to be accessed from OCaml. abstract guarantees an uniform representation of the values inside the OCaml heap and functions like Ctypes.addr can be applied to its values.

References:

Opaque

let%c myopaque = opaque "foo"
(* 'myopaque' will be of type 'myopaque Ctypes.typ' *)

opaque is similar to abstract, but will choose the best memory representation available for the type. If foo turns out to be an integer type, it will be an integer inside OCaml. If it is a pointer, it will be of type Ctypes.ptr - or Ctypes.abstract otherwise. opaque is preferable to abstract, if values of the corresponding type are usually passed by value.

Integers of Unknown Size and Signedness

module Signed_t = [%c int "foo"]
module Unsigned_t = [%c uint "foo"]
module Unknown_signed = [%c aint "foo"]
external foo : Signed_t.t -> void
let f t = Signed.add (Signed_t.of_int (-42)) t

module Signed_t = [%c int "foo"] creates an module Signed_t with the signature of Signed.S, and also include an additional value t of type t Ctypes.typ that can be used inside external declarations.

[%c uint "foo"] will create an analogous module with a signature of Unsigned.S.

[%c aint "foo"] will also be of type Unsigned.S, but with an additional value min_int that can be used to easily determine, if the type is signed or not. [%c int "foo"] and [%c uint "foo"] will throw an error during preprocessing, if the underlying type differs in signedness.

Integer types larger than 8 bytes are not supported.