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.