I am trying to interface with some legacy C code that takes both a callback function pointer and an opaque pointer to context to use as an argument when calling back. The function pointer generated by Julia is understood by C and calls back to Julia but the contents of the context seem to be lost. Here is a minimal working example:
# A minimal working example to show how we can get a Julia struct to
# round-trip through C
mutable struct context
test1::Int32
test2::Float64
test3::String
end
mutable struct handler_list
the_fun::Ptr{Nothing}
end
my_handler(a::context)::Cint = begin
println("$(a.test1)")
println("$(a.test2)")
println("$(a.test3)")
return 0
end
test() = begin
a = @cfunction(my_handler,Cint,(context,))
hl = handler_list(a)
my_context = context(1,2.0,"33333")
ccall((:set_and_run,"./libmwe"),Cint,(Ref{handler_list},Ref{context}),Ref(hl),Ref(my_context))
end
test()
and the C code is simply:
/* A small library function to demonstrate passing a struct to and from Julia */
typedef struct handler_s {
int (*handle_data)(void *context);
} handler_tp;
void set_and_run(handler_tp *f, void *context) {
f->handle_data(context);
}
The C code is compiled with gcc -g -shared -o libmwe.so mwe_struct.c
When I run this with julia mwe_struct.jl
I get a segfault. I have verified with gdb in the set_and_run
function that the context is a pointer that points to the beginning of my_context
.
So what am I doing wrong?