I want to use the Ctypes stubs Api like described in the following discussion :
Ctypes enum, how to make it work to bind my enums (previously, I used the easier way which is to use a view)
Here is the C enum declaration:
typedef enum
{
GI_INFO_TYPE_INVALID,
GI_INFO_TYPE_FUNCTION,
GI_INFO_TYPE_CALLBACK,
GI_INFO_TYPE_STRUCT,
GI_INFO_TYPE_BOXED,
GI_INFO_TYPE_ENUM, /* 5 */
GI_INFO_TYPE_FLAGS,
GI_INFO_TYPE_OBJECT,
GI_INFO_TYPE_INTERFACE,
GI_INFO_TYPE_CONSTANT,
GI_INFO_TYPE_INVALID_0, /* 10 */
GI_INFO_TYPE_UNION,
GI_INFO_TYPE_VALUE,
GI_INFO_TYPE_SIGNAL,
GI_INFO_TYPE_VFUNC,
GI_INFO_TYPE_PROPERTY, /* 15 */
GI_INFO_TYPE_FIELD,
GI_INFO_TYPE_ARG,
GI_INFO_TYPE_TYPE,
GI_INFO_TYPE_UNRESOLVED
} GIInfoType;
I have the following bindings.ml file:
type baseinfo_type =
| Invalid (** invalid type *)
| Function (** function, see Function_info *)
| Callback (** callback, see Function_info *)
| Struct (** struct, see Struct_info *)
| Boxed (** boxed, see Struct_info or Union_info *)
| Enum (** enum, see Enum_info *)
| Flags (** flags, see Enum_info *)
| Object (** object, see Object_info *)
| Interface (** interface, see Interface_info *)
| Constant (** contant, see Constant_info *)
| Invalid_0 (** deleted, used to be GI_INFO_TYPE_ERROR_DOMAIN. *)
| Union (** union, see Union_info *)
| Value (** enum value, see Value_info *)
| Signal (** signal, see Signal_info *)
| Vfunc (** virtual function, see VFunc_info *)
| Property (** GObject property, see Property_info *)
| Field (** struct or union field, see Field_info *)
| Arg (** argument of a function or callback, see Arg_info *)
| Type (** type information, see Type_info *)
| Unresolved (** unresolved type, a type which is not present in the typelib, or any of its dependencies. *)
module Enums = functor (T : Cstubs.Types.TYPE) -> struct
let gi_info_type_invalid = T.constant "GI_INFO_TYPE_INVALID" T.int64_t
let gi_info_type_function = T.constant "GI_INFO_TYPE_FUNCTION" T.int64_t
let gi_info_type_callback = T.constant "GI_INFO_TYPE_CALLBACK" T.int64_t
let gi_info_type_struct = T.constant "GI_INFO_TYPE_STRUCT" T.int64_t
let gi_info_type_boxed = T.constant "GI_INFO_TYPE_BOXED" T.int64_t
let gi_info_type_enum = T.constant "GI_INFO_TYPE_ENUM" T.int64_t
let gi_info_type_flags = T.constant "GI_INFO_TYPE_FLAGS" T.int64_t
let gi_info_type_object = T.constant "GI_INFO_TYPE_OBJECT" T.int64_t
let gi_info_type_interface = T.constant "GI_INFO_TYPE_INTERFACE" T.int64_t
let gi_info_type_constant = T.constant "GI_INFO_TYPE_CONSTANT" T.int64_t
let gi_info_type_invalid_0 = T.constant "GI_INFO_TYPE_INVALID_0" T.int64_t
let gi_info_type_union = T.constant "GI_INFO_TYPE_UNION" T.int64_t
let gi_info_type_value = T.constant "GI_INFO_TYPE_VALUE" T.int64_t
let gi_info_type_signal = T.constant "GI_INFO_TYPE_SIGNAL" T.int64_t
let gi_info_type_vfunc = T.constant "GI_INFO_TYPE_VFUNC" T.int64_t
let gi_info_type_property = T.constant "GI_INFO_TYPE_PROPERTY" T.int64_t
let gi_info_type_field = T.constant "GI_INFO_TYPE_FIELD" T.int64_t
let gi_info_type_arg = T.constant "GI_INFO_TYPE_ARG" T.int64_t
let gi_info_type_type = T.constant "GI_INFO_TYPE_TYPE" T.int64_t
let gi_info_type_unresolved = T.constant "GI_INFO_TYPE_UNRESOLVED" T.int64_t
let baseinfo_type = T.enum "baseinfo_type" [
Invalid, gi_info_type_invalid;
Function, gi_info_type_function;
Callback, gi_info_type_callback;
Struct, gi_info_type_struct;
Boxed, gi_info_type_boxed;
Enum, gi_info_type_enum;
Flags, gi_info_type_flags;
Object, gi_info_type_object;
Interface, gi_info_type_interface;
Constant, gi_info_type_constant;
Invalid_0, gi_info_type_invalid_0;
Union, gi_info_type_union;
Value, gi_info_type_value;
Signal, gi_info_type_signal;
Vfunc, gi_info_type_vfunc;
Property, gi_info_type_property;
Field, gi_info_type_field;
Arg, gi_info_type_arg;
Type, gi_info_type_type;
Unresolved, gi_info_type_unresolved;
]
~unexpected:(fun _x -> assert false)
end
And a bindings_c_gen.ml file :
let c_headers = "#include <girepository.h>"
let main () =
let stubs_out = open_out "bindings_stubs_gen.c" in
let stubs_fmt = Format.formatter_of_out_channel stubs_out in
Format.fprintf stubs_fmt "%s@\n" c_headers;
Cstubs.Types.write_c stubs_fmt (module Bindings.Enums);
Format.pp_print_flush stubs_fmt ();
close_out stubs_out
let () = main ()
Which generates a bindings_stubs_gen.c file. The problem comes when I try to compile it, I have the following error:
LANG=en_EN-UTF-8 dune build bin/main.exe
bash stubgen/bindings_stubs_gen.exe (exit 1)
(cd _build/default/stubgen && /usr/bin/bash -e -u -o pipefail -c 'gcc -O2 -fno-strict-aliasing -fwrapv -fPIC bindings_stubs_gen.c -I `dirname /home/ce
dlemo/.opam/default/lib/ctypes/ctypes_cstubs_internals.h` -I /home/cedlemo/.opam/default/lib/ocaml -o bindings_stubs_gen.exe $(< gi-ccopt) $(< gi-ccli
b)')
In file included from /home/cedlemo/.opam/default/lib/ctypes/ctypes_cstubs_internals.h:13,
from bindings_stubs_gen.c:8:
bindings_stubs_gen.c: In function 'main':
bindings_stubs_gen.c:180:74: error: conversion to incomplete type
ctypes_arithmetic_type_name(CTYPES_CLASSIFY_ARITHMETIC_TYPE(enum baseinfo_type)));
^~~~~~~~~~~~~
/home/cedlemo/.opam/default/lib/ctypes/ctypes_primitives.h:143:17: note: in definition of macro 'CTYPES_CHECK_FLOATING'
((unsigned)(((TYPENAME) 0.5) != 0) << CTYPES_FLOATING_FLAG_BIT)
^~~~~~~~
/home/cedlemo/.opam/default/lib/ctypes/ctypes_primitives.h:148:47: note: in expansion of macro 'CTYPES_CLASSIFY'
#define CTYPES_ARITHMETIC_TYPEINFO(TYPENAME) (CTYPES_CLASSIFY(TYPENAME) \
^~~~~~~~~~~~~~~
/home/cedlemo/.opam/default/lib/ctypes/ctypes_primitives.h:151:35: note: in expansion of macro 'CTYPES_ARITHMETIC_TYPEINFO'
ctypes_classify_arithmetic_type(CTYPES_ARITHMETIC_TYPEINFO(TYPENAME))
^~~~~~~~~~~~~~~~~~~~~~~~~~
bindings_stubs_gen.c:180:37: note: in expansion of macro 'CTYPES_CLASSIFY_ARITHMETIC_TYPE'
ctypes_arithmetic_type_name(CTYPES_CLASSIFY_ARITHMETIC_TYPE(enum baseinfo_type)));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bindings_stubs_gen.c:180:74: error: conversion to incomplete type
ctypes_arithmetic_type_name(CTYPES_CLASSIFY_ARITHMETIC_TYPE(enum baseinfo_type)));
^~~~~~~~~~~~~
/home/cedlemo/.opam/default/lib/ctypes/ctypes_primitives.h:145:17: note: in definition of macro 'CTYPES_CHECK_UNSIGNED'
((unsigned)(((TYPENAME) -1) > 0) << CTYPES_UNSIGNED_FLAG_BIT)
^~~~~~~~
/home/cedlemo/.opam/default/lib/ctypes/ctypes_primitives.h:148:47: note: in expansion of macro 'CTYPES_CLASSIFY'
#define CTYPES_ARITHMETIC_TYPEINFO(TYPENAME) (CTYPES_CLASSIFY(TYPENAME) \
^~~~~~~~~~~~~~~
/home/cedlemo/.opam/default/lib/ctypes/ctypes_primitives.h:151:35: note: in expansion of macro 'CTYPES_ARITHMETIC_TYPEINFO'
ctypes_classify_arithmetic_type(CTYPES_ARITHMETIC_TYPEINFO(TYPENAME))
^~~~~~~~~~~~~~~~~~~~~~~~~~
bindings_stubs_gen.c:180:37: note: in expansion of macro 'CTYPES_CLASSIFY_ARITHMETIC_TYPE'
ctypes_arithmetic_type_name(CTYPES_CLASSIFY_ARITHMETIC_TYPE(enum baseinfo_type)));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bindings_stubs_gen.c:180:69: error: invalid application of 'sizeof' to incomplete type 'enum baseinfo_type'
ctypes_arithmetic_type_name(CTYPES_CLASSIFY_ARITHMETIC_TYPE(enum baseinfo_type)));
^~~~
/home/cedlemo/.opam/default/lib/ctypes/ctypes_primitives.h:149:54: note: in definition of macro 'CTYPES_ARITHMETIC_TYPEINFO'
| sizeof(TYPENAME))
^~~~~~~~
bindings_stubs_gen.c:180:37: note: in expansion of macro 'CTYPES_CLASSIFY_ARITHMETIC_TYPE'
ctypes_arithmetic_type_name(CTYPES_CLASSIFY_ARITHMETIC_TYPE(enum baseinfo_type)));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The part of bindings_stubs_gen.c that fails, is the following:
printf(" | \"baseinfo_type\" -> \n Cstubs_internals.build_enum_type \"baseinfo_type\" Ctypes_static.%s ?typedef ?unexpected alist\n",
ctypes_arithmetic_type_name(CTYPES_CLASSIFY_ARITHMETIC_TYPE(enum baseinfo_type)));
puts(" | s ->");
puts(" failwith (\"unmatched enum: \"^ s)");
I don’t know how to fix this.