Я пишу OCaml-обертки для нескольких функций C, которые используют идиому out-parameter и возвращают код ошибки. Я обернул их, выделив массив C на стороне OCaml, используя Ctypes.allocate_n
. А затем скопируйте содержимое в тип OCaml.
Я чувствую, что я взламываю проблему, что Ctypes
или какой-то другой модуль уже решает по-другому, вот пример.
gethostname(2)
имеет следующий тип:
int gethostname(char *name, size_t len);
Здесь out_parameter.mli
для обернутой функции gethostname
.
val gethostname : int -> [> `Ok of string | `Error of int];;
Здесь реализация
open Core.Std;;
let (@->) = Ctypes.(@->);;
let returning = Ctypes.returning;;
open Foreign;;
let gethostname size =
let size' = Unsigned.Size_t.of_int size in
let c_gethostname =
foreign "gethostname" (Ctypes.ptr Ctypes.char @-> Ctypes.size_t @-> returning Ctypes.int) in
let buf = Ctypes.allocate_n Ctypes.char ~count:size in
let err = c_gethostname buf size' in
match err with
| 0 -> (
`Ok (Ctypes.string_from_ptr buf ~length:size)
)
| _ -> `Error err;;
let main () =
Printf.printf "%s\n" (match gethostname 1000 with
| `Ok hostname -> hostname
| `Error _ -> "error getting hostname");;
let () = main ();;
И для компиляции я скомпилировал out_parameter.native
с помощью этой команды.
$ corebuild -pkg ctypes.foreign out_parameter.native
Код действительно работает и возвращает имя хоста, с завершающим нулевым байтом.
$ ./out_parameter.native
MY-HOSTNAME
$ ./out_parameter.native | sed -e 's/\x0/@/g'
MY-HOSTNAME