Consider the following C API:
struct Options {
uint32_t a;
uint32_t b;
void* extra;
};
struct OptionsExtra {
uint32_t c;
uint32_t d;
};
void foo(struct Options const* options);
It can be used from C as follows:
foo(&(struct Options) {
.a = 1,
.b = 2,
.extra = &(struct OptionsExtra) {
.c = 3,
.d = 4,
}
});
I redeclared this API in Julia:
struct Options
a::UInt32
b::UInt32
extra::Ptr{Cvoid}
end
struct OptionsExtra
c::UInt32
d::UInt32
end
function foo(options)::Cvoid
ccall((:foo, lib), Cvoid, (Ref{Options},), options)
end
How should I construct extra
pointer in a call to foo
?
extra = OptionsExtra(3, 4)
foo(Options(1, 2, #= what goes here? =#))
pointer
function only works with arrays and pointer_from_objref
only with mutable objects.
As a workaround I can put extra
in an array:
extra = [OptionsExtra(3, 4)]
GC.@preserve extra foo(Options(1, 2, pointer(extra)))
But this seems overcomplicated and suboptimal as it involves heap allocation while C version allocates everything on the stack.
Is there any better way to do this?