Closed coffeebe4code closed 1 year ago
The issue is that cbindgen can't find the FunctionBuilder
at all, but it does the right thing if you define it:
struct FunctionBuilder {}
#[no_mangle]
pub extern "C" fn CL_FunctionBuilder_finalize(builder: *mut FunctionBuilder) -> () {
let ubuilder = unsafe {
assert!(!builder.is_null());
core::ptr::read(builder)
};
ubuilder.finalize();
}
So this works, it's just a matter of the specific thing you're doing. If FunctionBuilder
is on a different crate you probably need to let cbindgen run on that crate too?
@emilio
If FunctionBuilder is on a different crate you probably need to let cbindgen run on that crate too?
I'm not sure what you mean. FunctionBuilder
is defined in another crate. cranelift
to be precise. It has no C compatible API's. I am trying to expose a C compatible api. However, I don't want to figure out how to make every struct and every property c compatible, and then do a translation from a #[repr(C)]
struct to #[repr(Rust)]
. I want FunctionBuilder to be treated as essentially a typedef to a void pointer, and let rust deal with everything on that object.
I know I can make a struct transparent like so.
#[repr(transparent)]
pub struct CVariable(u32);
And this translation is incredibly easy. I'm just hoping there is something similar for an opaque pointer.
I'm just hoping there is a way to do what I am looking for. Please let me know if there is anything close. This is my first time using cbindgen, and the docs didn't quite cover something like this.
Let me know if there is a better way, but I did this to "resolve" my issue. I have yet to get the tool to fully work based on a different issue I have open. But this should theoretically work.
I created a craneliftc_extra.h
file, and put my typedefs in there, and then specified the include in cbindgen.toml for those extras.
cbindgen.toml
includes = ["craneliftc_extra.h"]
craneliftc_extra.h
typedef void *FunctionBuilder;
typedef void *UserFuncName;
typedef void *Flags;
typedef void *AbiParam;
typedef void *Builder;
typedef void *Signature;
typedef void *FunctionBuilderContext;
typedef void *Function;
@emilio
If FunctionBuilder is on a different crate you probably need to let cbindgen run on that crate too?
I'm not sure what you mean.
FunctionBuilder
is defined in another crate.cranelift
to be precise. It has no C compatible API's. I am trying to expose a C compatible api. However, I don't want to figure out how to make every struct and every property c compatible, and then do a translation from a#[repr(C)]
struct to#[repr(Rust)]
. I want FunctionBuilder to be treated as essentially a typedef to a void pointer, and let rust deal with everything on that object.
Right, I think you can do something like this to make sure cbindgen visits the cranelift
crate, even tho there's no FFI-compatible thing there.
You probably want struct FunctionBuilder;
etc rather than typedef void* FunctionBuilder;
in any case, so that a pointer to FunctionBuilder
cannot be dereferenced.
I am attempting to turn a non c api compatible pointer back to the caller.
I just want to treat it as an opaque pointer. I'm not interested in converting all the fields and making a
repr(C)
compatible struct.Here is an example.
Is there any way to tell cbindgen to honor this?