I am trying to create a sys-library crate libindigo-sys for INDIGO using bindgen.
So far it works on Mac, but when I try to compile the rust libindigo wrapper library on Linux, I run into the following problem:
error[E0308]: mismatched types
--> src/server.rs:23:17
|
23 | thread: ptr::null_mut(),
| ^^^^^^^^^^^^^^^ expected `u64`, found `*mut _`
|
= note: expected type `u64`
found raw pointer `*mut _`
Evidently the pthreads are managed differently on Linux and Mac, no surprise there.
The error above relates to this snippet:
let mut entry = indigo_server_entry {
name: name,
host: host,
port: port,
connection_id: 0,
thread: ptr::null_mut(), // <-- bindgen on Mac produces a pointer, not an u64
thread_started: false,
socket: 0,
protocol_adapter: ptr::null_mut(),
last_error: [0; 256],
shutdown: false,
};
Note that I only need to create instances of this struct and provide it to various C functions, I do not need to manipulate these threads in my Rust code.
Question is, how do I manage this in my wrapper code?
A quick hack for it could be to use std::mem::zeroed() which will give you a zero value for pointers and integers.
You could also try defining types and default values for it in Rust, using #[cfg(target_os = "macos")] and similar (see cfg_if), if the types change predictably on the platforms you support.
If the required type is exported by the C headers as a typedef, then bindgen should generate it. If there isn't a typedef, you could make one yourself by including original .h files in your wrapper.h.
If the types are too C-specific or too platform-specific, you could write a C function for initializing this struct, and build and link that C code as part of your sys crate.
This "quick hack" works perfectly for the Mac/Linux difference, will be interesting to know when what happens when I test it on Windows...
You could also try defining types and default values for it in Rust, using #[cfg(target_os = "macos")] and similar (see cfg_if), if the types change predictably on the platforms you support.
Would this work though?
The code generated on a Mac requires a ptr::null_mut and on Linux, the bindgen code requires a u64 integer instead.
Note that I don't really care about the field as long as it gets intialised to zero or null, whatever is suitable on the platform. The C code will set it to the correct platform-specific value when the server is starting.
If the required type is exported by the C headers as a typedef, then bindgen should generate it. If there isn't a typedef, you could make one yourself by including original .h files in your wrapper.h .
The type does get generated, the issue is that bindgen generates (slightly) different code on Mac and Linux.
If the types are too C-specific or too platform-specific, you could write a C function for initializing this struct, and build and link that C code as part of your sys crate.
This would be the very last resort for me, but it is a good and valid option I think. Might be the cleanest although I would have to include custom c-code in my Rust crate instead of just relying on the upstream lib.
Thanks a lot for the pointers, they helped me to move on to the next issue regarding linking the static lib file...