Description
Input C Header
#define MACRO_ARRAY {1, 2}
static const int static_const_array[] = {3, 4};
Bindgen Invocation
$ bindgen input.h
Actual Results
extern "C" {
#[link_name = "\u{1}static_const_array"]
pub static mut static_const_array: [::std::os::raw::c_int; 2usize];
}
(The presence of the mut
is #511, it's not the point of this issue but I'm just noting that that's a separate incorrect thing here.)
Expected Results
As it is, neither array can be used with bindgen
alone. MACRO_ARRAY
is not emitted and attempting to use static_const_array
will result in a link error, because there is no definition, only a declaration.
I was hoping to see at least:
static static_const_array: [::std::os::raw::c_int; 2usize] = [3, 4];
And ideally:
// Inferred as c_int based on the types of 1 and 2
static MACRO_ARRAY: [::std::os::raw::c_int; 2usize] = [1, 2];
static static_const_array: [::std::os::raw::c_int; 2usize] = [3, 4];
I figure that cases like MACRO_ARRAY
are difficult in general, relating to issues like #316. But if at least the static_const_array
case would work, it could be used as a simple workaround for the macro support.
Workaround
As it is, one has to write and compile some C (typically involving the cc crate) that provides a symbol to hold the array value, and in the non-macro case a way of initializing it because C can't do it at compile time. For example:
#include <string.h>
#define MACRO_ARRAY {1, 2}
static const int static_const_array[] = {3, 4};
const int my_macro_array[] = MACRO_ARRAY;
int my_static_const_array[sizeof(static_const_array) / sizeof(static_const_array[0])];
void my_static_const_array_init(void) {
memcpy(my_static_const_array, static_const_array, sizeof static_const_array);
}
And then in the bindgen
stub declare e.g.:
const int my_macro_array[sizeof((int[])MACRO_ARRAY) / sizeof(int)] = MACRO_ARRAY;
extern int my_static_const_array[sizeof(static_const_array) / sizeof(static_const_array[0])];
extern void my_static_const_array_init(void);
And finally, arrange a way of calling my_static_const_array_init
when needed.
Needless to say, this is quite painful. :-) I'm open to better approaches, this is just the most straightforward thing off the top of my head.