Ctypes passing string pointer or null pointer

Hi all,

I’m trying to wrap some basic Linux syscall and sometimes I have case in which I want to pass a pointer to a string or a null pointer.

Let’s take mount(2) as an example, I may want to pass NULL as 3rd parameter, so in OCaml

  let _mount =
  foreign "mount" (ptr char @-> ptr char  @-> ptr_opt char  @-> int @-> ptr void @-> returning int)

  let mount source target fstype oflags =
    let flags = 0 in
    let flags = List.fold_left (fun (flags:int) (e:flag) ->
      flags lor (flag_to_int e)
    ) flags oflags
    in
    let csource = CArray.of_string source in
    let ctarget = CArray.of_string target in
    let cfstype =
      match fstype with
      | Some fs -> Some (CArray.of_string fs)
      | None -> None
    in
    _mount  csource ctarget cfstype flags (Ctypes.null)

The problem is that offcourse I get an error on the types when I try to build

Error: This expression has type char carray
       but an expression was expected of type
         char Ctypes_static.ptr = (char, [ `C ]) pointer

I have also tried by using Ctypes.null in the pattern matching, but offcourse I get the same error
Any suggestion?

Thanks,
Gabriele

Just solved, I should use CArray.start to get the actual pointer to the string
So the code becomes like this:

let _mount =
foreign "mount" (ptr char @-> ptr char  @-> ptr_opt char  @-> int @-> ptr void @-> returning int)

  let mount source target fstype oflags =
    let flags = 0 in
    let flags = List.fold_left (fun (flags:int) (e:flag) ->
      flags lor (flag_to_int e)
    ) flags oflags
    in
    let csource = CArray.start (CArray.of_string source) in
    let ctarget = CArray.start (CArray.of_string target) in
    let cfstype =
      match fstype with
      | Some fs -> Some (CArray.start (CArray.of_string fs))
      | None -> None
    in
    _mount  csource ctarget cfstype flags (Ctypes.null)

You can use string_opt to let Ctypes do conversion from/to string option for you.

Another option is to use coerce:

Ctypes.(coerce (ptr void) (ptr char) null)

Thanks @osener indeed I will switch to string_opt also because the signature of the C is using const char * it will not need to modify/write to the string so it seems more clean to pass them in that way

Thanks!!