I have an extern "C" interface to some dynamically loaded code. For that code some objects are opaque handles, expressed as void*
. The interface looks like this:
extern "C" {
void* get_foo() { Foo* foo = /* create and remember object */; return foo; }
int foo_get_bar(void* Foo) { return ((Foo*)foo)->bar(); }
}
Such pattern are pretty much the standard way to interact with C++ objects across a C-API, AFAIK. But I wonder if I can omit that pointer cast?
The caller of the code is generated and only linked against the interface above (it has its own function declarations). So it effectively generates code like this:
void foo_get_bar(void*);
void* get_foo();
int do_something() { return foo_get_bar(get_foo()) };
We can assume that the caller uses the code correctly (i.e., it does not pass wrong pointers). But of course it has no notion of a Foo
pointer.
Now could I change the interface to the (simpler) variant:
extern "C" {
int foo_get_bar(Foo* Foo) { return foo->bar(); }
}
Or is there a subtle difference between void*
and Foo*
at the linker level (could e.g., the sizes not match up?).
edit: I might have caused some confusion with the caller code in C. There is no C code. There is no C compiler and thus no C type checker involved. The caller code is generated and it uses the C-API. So to use an opaque struct I would need to know how the C-API represents that pointer after compilation.