What type to use for 2D arrays in ccall

I am experimenting with calls to C functions, and got a bit puzzled when using multi-dimensional arrays as parameters.

I have this bit of C code in cfile.c:

void f(double array[2][2])
{
    array[1][1] = 42.;
    return;
}

which I compile with gcc -fPIC -c cfile.c && gcc -shared -fPIC cfile.o -o cfile.so. Then I import the function in Julia :

using Libdl

lib = Libdl.dlopen("./cfile.so")
func = Libdl.dlsym(lib, :f)

a = rand(Cdouble, 2, 2)
ccall(func, Cvoid, (Ref{Ref{Cdouble}}, ), a)
println(a)

Libdl.dlclose(lib)

Now with this bit of code, a doesn’t change. However, if I use (Ptr{Cvoid}, ) as parameter type in the ccall, it works as intended. And if I use Ptr{Ptr{Cdouble}}, I get an error:

ERROR: LoadError: MethodError: no method matching unsafe_convert(::Type{Ptr{Float64}}, ::Float64)

Is there something I don’t do right? Or should I simply use Ptr{Cvoid} with multi-dimensional arrays?

I believe that Ptr{Cdouble} should be fine. Passing multidimensional arrays around in C is notoriously difficult to get right and unless you are an expert C programmer I would advise against using them at all. Cf.

1 Like

This is working indeed! Although I still don’t get what’s happening with the other declarations, I will use this. Unfortunately, I have to use 2D arrays (in the real use case, I am calling a library function which modifies a 2D array passed as parameter). I could wrap the function to flatten them though… Is this what would be the best?