Why this code does a segfault?

,

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 :slight_smile: 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