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?