cbindgen
cbindgen copied to clipboard
Using libc::[some c-struct] in function gets export without struct keyword
Hi
I'm writing a Rust library with C interface where I'm using libc structs in function arguments. The generated header file then ends up with type like "sockaddr" instead of "struct sockaddr".
I solved this by renaming like this
[export.rename]
"sockaddr" = "struct sockaddr"
Is this the way to go or am I missing a "nicer" solution?
What is the whole configuration you're using?
autogen_warning = "/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */"
language = "C"
includes = []
no_includes = false
sys_includes = ["stdint.h", "sys/epoll.h", "sys/socket.h"]
[parse]
parse_deps = false
[export.rename]
"epoll_event" = "struct epoll_event"
"sockaddr" = "struct sockaddr"
Hmm, right... I think the issue is that cbindgen is not parsing epoll_event
/ sockaddr
so it doesn't really know it's a struct rather than e.g. an enum.
We could conceptually get some knowledge about libc in cbindgen, but that seems a bit brittle and lacking that... I don't think there's an straight-forward solution.
Does using parse_deps = true
get the right info?
Does using parse_deps = true get the right info?
Nope... It's fine, it's a minor issue and renaming works fine. A bigger issue with build.rs is that cbindgen runs before rustc so any build errors are detected by cbindgen instead of rustc so I moved it to a Makefile instead. I wish we had pre/post build script support in cargo...
Yeah... in practice in Firefox we use cbindgen from the cli interface for these kinds of things.
I was unable to get renaming working because cbindgen has apparently become clever in the last few years and knows that e.g. struct in_addr
is not a valid name and so replaces the space with an underscore, making it struct_in_addr
in my header.
I have managed to 'trick' cbindgen into working by:
lib.rs
/// cbindgen:no-export=true
#[allow(non_camel_case_types, unused)]
struct in_addr;
fn x() -> libc::in_addr { ... }
cbindgen then:
- sees x requires an
in_addr
definition - spots an opaque (i.e. not
repr(C)
) struct that matches in_addr and so knows it's a struct - does not actually emit an opaque struct declaration (i.e.
typedef struct in_addr in_addr;
) because of theno-export
annotation
Which ends up with correct usage of in_addr
without creating a definition that conflicts with the header file.
no-export
was undocumented, which I have a PR to fix at #897.
Note that this workaround may break if #7 gets fixed.