I am attempting to make a julia wrapper for a C library. The C library is already available as a jll. I was attempting to use Clang.jl to make the wrapper, but whatever I am doing seems to be causing segfaults on garbage collection.
Here is what Clang.jl generates for me (only the minimal amount of bindings to show the problem) and the segfault it causes:
I am wrapping the graph theory library igraph
, in particular I am creating an empty struct igraph_t
representing a graph, then initializing it to be the “4 nodes and 0 edges” graph by using igraph_empty
.
# bindings generated by Clang.jl and selectively copied here by me
using igraph_jll
using CEnum
@cenum igraph_error_type_t::UInt32 begin
IGRAPH_SUCCESS = 0
IGRAPH_FAILURE = 1
# ... skip a bunch of other options
end
const igraph_error_t = igraph_error_type_t
const igraph_integer_t = Int64
const igraph_bool_t = Bool
mutable struct igraph_i_property_cache_t end
mutable struct igraph_vector_int_t
stor_begin::Ptr{igraph_integer_t}
stor_end::Ptr{igraph_integer_t}
_end::Ptr{igraph_integer_t}
igraph_vector_int_t() = new()
end
mutable struct igraph_s
n::igraph_integer_t
directed::igraph_bool_t
from::igraph_vector_int_t
to::igraph_vector_int_t
oi::igraph_vector_int_t
ii::igraph_vector_int_t
os::igraph_vector_int_t
is::igraph_vector_int_t
attr::Ptr{Cvoid}
cache::Ptr{igraph_i_property_cache_t}
igraph_s() = new()
end
const igraph_t = igraph_s
function igraph_empty(graph, n, directed)
ccall((:igraph_empty, libigraph), igraph_error_t, (Ptr{igraph_t}, igraph_integer_t, igraph_bool_t), graph, n, directed)
end
##
# simple usage example that segfaults
a = igraph_s();
igraph_empty(pointer_from_objref(a), 4, false)
GC.gc() # segfaults
Any idea where I am going wrong? Introspecting some of the properties of a
like a.n
and a.directed
gives me the expected values, but looking at a.to
which should be storing the destination for each edge causes a segfault.