Looks like you somehow think that it’s OK to use Ref
and Ptr
interchangeably. Ref
and Ptr
are actually two different things and you should use it properly. If any section of the Julia documentation makes you think of that, please point that out, so we can fix it.
2 Likes
@Gnimuc Seems to be good now while I did not fully check my whole application code Thanks for Clang.jl that I did not know, but types were correct, but you are right I was confusing Ref and Ptr within ccall definition: Ptr is also for input-output pointers and Julia will let C managing pointers (that is what I wanted).
Thanks for your help !
Correct code is the following:
C
// gcc foo.c -fpic -shared -o libfoo.so
#include <stdio.h>
#include <assert.h>
struct mystruct
{
double* data;
size_t size;
};
typedef struct mystruct mystruct_t;
void recvstruct(mystruct_t const* st)
{
assert(st != NULL);
printf("mystruct=%g, %g, %g (%zu)\n",
st->data[0], st->data[1], st->data[2], st->size);
}
void updatestruct(mystruct_t* st)
{
static double values[16] = { 1.0, 2.0, 3.0 };
assert(st != NULL);
st->data = values;
st->size = 3u;
}
Julia
struct Mystruct
data::Ptr{Cdouble}
size::Csize_t
Mystruct() = new(Ptr{Cdouble}(), 0)
end
function print_struct(v::Ref{Mystruct})
# Ptr !!!!
ccall((:recvstruct, "./libfoo.so"), Cvoid, (Ptr{Mystruct},), v)
end
function update_struct()
st = Ref(Mystruct())
ccall((:updatestruct, "./libfoo.so"), Cvoid, (Ptr{Mystruct},), st)
print_struct(st)
V = Vector{Cdouble}(undef, st[].size)
for i in 1:st[].size
V[i] = unsafe_load(st[].data, i)
end
return V
end
V = update_struct()
show(V)
3 Likes