Open rand00 opened 11 months ago
I think this is a good idea, I didn't put much effort into wrapping the input structures when I wrote the library. I'll try and find some time to update it.
Earlier today I also had some success defining a full bulk loop. I needed the following struct for gpiod_line_bulk
:
module Line_bulk = struct
let t = Gpiod.gpiod_line_bulk
let lines = Ctypes.field t "lines" (Ctypes.ptr_opt Line.t)
let num_lines = Ctypes.field t "num_lines" Ctypes.uint
let () = Ctypes.seal t
end
And also needed these procedures / getters (couldn't bind to the field-getters for gpiod_line_bulk
, so defined them in Ctypes):
(*
int gpiod_line_event_wait_bulk (
struct gpiod_line_bulk * bulk,
const struct timespec * timeout,
struct gpiod_line_bulk * event_bulk
)
*)
let line_event_wait_bulk =
Foreign.foreign "gpiod_line_event_wait_bulk"
Ctypes.(
ptr_opt Struct.Line_bulk.t
@-> ptr_opt Struct.Timespec.t
@-> ptr_opt Struct.Line_bulk.t
@-> returning int
)
(*> fix?: Error: undefined symbol*)
(*static unsigned int gpiod_line_bulk_num_lines (
struct gpiod_line_bulk * bulk
)
*)
(* let line_bulk_num_lines = *)
(* Foreign.foreign "gpiod_line_bulk_num_lines" *)
(* Ctypes.( *)
(* ptr_opt Struct.Line_bulk.t *)
(* @-> returning uint *)
(* ) *)
let line_bulk_num_lines line_bulk =
Ctypes.getf
line_bulk
Struct.Line_bulk.num_lines
(*
static struct gpiod_line* gpiod_line_bulk_get_line (
struct gpiod_line_bulk * bulk,
unsigned int offset
)
*)
(* let line_bulk_get_line = *)
(* Foreign.foreign "gpiod_line_bulk_get_line" *)
(* Ctypes.( *)
(* ptr_opt Struct.Line_bulk.t *)
(* @-> uint *)
(* @-> returning (ptr_opt Struct.Line.t) *)
(* ) *)
let line_bulk_get_line line_bulk ~len i =
let lines_ptr =
Ctypes.getf line_bulk Struct.Line_bulk.lines
|> CCOption.get_exn_or "ERROR: Gpiod_aux.line_bulk_get_line: lines was None"
in
let lines_arr = Ctypes.CArray.from_ptr lines_ptr len in
Ctypes.CArray.get lines_arr i
(*
int gpiod_chip_get_lines (
struct gpiod_chip * chip,
unsigned int * offsets,
unsigned int num_offsets,
struct gpiod_line_bulk * bulk
)
*)
let chip_get_lines =
Foreign.foreign "gpiod_chip_get_lines"
Ctypes.(
ptr_opt Struct.Chip.t
@-> ptr_opt uint
@-> uint
@-> ptr_opt Struct.Line_bulk.t
@-> returning int
)
(*
int gpiod_line_get_value_bulk (
struct gpiod_line_bulk * bulk,
int * values
)
*)
let line_get_value_bulk =
Foreign.foreign "gpiod_line_get_value_bulk"
Ctypes.(
ptr_opt Struct.Line_bulk.t
@-> ptr_opt int
@-> returning int
)
It's not fully tested yet, but seemed to work. Btw. I e.g. rebound the Gpiod.line_get_value_bulk
because it had a ptr void
instead of ptr int
as second argument - why does it have this interface?
I needed to use the
Gpiod.line_event_read_multiple
and found that I needed to construct the C struct of theGpiod.gpiod_line_event
myself, to read the different types of events.I didn't know Ctypes much beforehand, so needed to take a dive into it to find out what to do - should the struct maybe be defined and sealed by the library? Otherwise I think it would be nice with an example for users.
The Cstruct I ended up with was: