I’m trying to write C library bindings, and could use a few pointers and guidance as LLMs I’ve tried hallucinate a lot on this topic.
What I’m struggling with at the moment is reading a single character at a time from a char ptr
type. Currently I’m using the string_from_ptr
function, but I could use a “char_from_ptr” equivalent.
let single_char_string = string_from_ptr ~length:1 (my_char_pointer +@ 0)
At the same time, I’d like to know what is the correct representation, in program source code, of the null byte when comparing? LLMs hallucinate it as '\000'
, which is a syntax error due to the backslash, but it seems to work when I compare with "\000"
. But that doesn’t look right at all.
Attached is a slice of my code for reference or if anyone can provide suggestions specifically when interfacing with C.
let listxattr: string -> char Ctypes_static.ptr -> int -> int =
foreign "listxattr" ~check_errno:true (string @-> ptr char @-> int @-> returning int)
let list_attribute_names path =
(* between calls of listxattr size of buffer may differ *)
(* repeat size query and retrieval until lengths match *)
(* in theory, in code will still need to move the check `names_ln` within the loop *)
let rec read_reallocate_until_aligned expected_length =
let buffer = allocate_n char ~count:expected_length in
let copied_count = listxattr path buffer expected_length in
if copied_count <> expected_length then read_reallocate_until_aligned copied_count
else (expected_length, buffer) in
let names_ln = listxattr path Ctypes.(coerce (ptr void) (ptr char) null) 0 in
let (len, names) = read_reallocate_until_aligned names_ln in
for i = 0 to len do
let c = string_from_ptr ~length:1 (names +@ i) in <-----------------------
if c = "\000" then print_endline "" else
Printf.printf "%s" c;
()
done;
()
let () = list_attribute_names "/proc/self/exe"