C array of function pointers

I’m working on wrapping some C code, and one of the fundamental objects in the library is an array of function pointers. I can obtain a pointer to the object with dlsym fine, but when I try to wrap the pointer into an array I get a ReadOnlyMemoryError() and Julia crashes.

Here is a minimal example (not runnable b.c. Lints isn’t registered yet).

julia> using Lints

julia> using Libdl

julia> Lints.init()

julia> X = dlsym(Lints.libint2,:libint2_build_eri)
Ptr{Nothing} @0x00007f1c494fab80

julia> unsafe_wrap(Array,reinterpret(Ptr{Function},X),(7,7,7,7))
Internal error: encountered unexpected error in runtime:
[huge stacktrace]

Any ideas about how to work with such an object (C array of function pointers that I need to pass to ccall).

You’re not far off, but you need to make a couple of changes. First of all, Ptr{Function} isn’t the right type: that would be a pointer to the Julia abstract type Function, which isn’t the same as a C function. Second, you have an array of function pointers, so you need to treat it as a pointer-to-pointer-to-function.

For bonus points, here’s a complete working example because I’m still waiting for my non-Julia code to compile at work:

julia> C_code = """

       int times_two(int x) {
           return x * 2;

       int times_three(int x) {
           return x * 3;

       int (*functions[2])(int) = {times_two, times_three};


julia> using Libdl

julia> const Clib = tempname() * "." * Libdl.dlext

julia> open(`gcc -fPIC -O3 -msse3 -xc -shared -o $Clib -`, "w") do cmd
           print(cmd, C_code) 

julia> lib = Libdl.dlopen(Clib)
Ptr{Nothing} @0x0000000000dece20

julia> X = dlsym(lib,:functions)
Ptr{Nothing} @0x00007f4968c50030

julia> functions = unsafe_wrap(Array, reinterpret(Ptr{Ptr{Cvoid}}, X), 2)
2-element Array{Ptr{Nothing},1}:
 Ptr{Nothing} @0x00007f4968a4f600
 Ptr{Nothing} @0x00007f4968a4f610

julia> ccall(functions[1], Cint, (Cint,), 2)

julia> ccall(functions[2], Cint, (Cint,), 2)

Ah, I see now. Still getting the hang of working with the C interface. Thank you!