Passing a Ptr{Ptr{Int64}} in ccall

I have gone down a rabbit hole after reading https://github.com/lh3/biofast and somehow have ended up writing an interface to the C code in cgranges. A couple of the functions that I want to call through ccall take an argument that is a Ptr{Ptr{Int64}}, allocate storage using malloc within the function call, and populate the vector.

It has been too long since I subjected myself to this sort of task and I can’t remember how to create the object in Julia to be passed through ccall and later deferenced. In C the code looks like


	int64_t i, n, *b = 0, max_b = 0;
	n = cr_overlap(cr, "chr1", 15, 22, &b, &max_b); // overlap query; output array b[] can be reused
	for (i = 0; i < n; ++i) // traverse overlapping intervals
		printf("%d\t%d\t%d\n", cr_start(cr, b[i]), cr_end(cr, b[i]), cr_label(cr, b[i]));
	free(b); // b[] is allocated by malloc() inside cr_overlap(), so needs to be freed with free()

In a Julia function of the form

function cr_overlap(cr, ctg, st, en, b_, m_b_)
    ccall((:cr_overlap, libcgranges), Int64, (Ptr{cgranges_t}, Ptr{Cchar}, Int32, Int32, Ptr{Ptr{Int64}}, Ptr{Int64}), cr, ctg, st, en, b_, m_b_)
end

I can’t figure out what to pass as b_.

How about

b = [Ptr{Int64}(0)]

Based on the description here (last paragraph under Array{T,N}).

For this case I’ve used:

Ref{Ptr{Int}}()

Which can convert to **int nicely. It’s basically equivalent to the previous array example but is a little more semantic in my opinion.

1 Like

Thank you. That works well.