Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correct way to call C function from Julia with call-by-reference?

Tags:

c

julia

What is the correct way to call C function from Julia with call-by-reference?

I'm trying to call a C function with ccall from Julia which gets its outputs as pointers.

So the C function should do something like this:

    void plusOne(int* i){
        printf("C: i = %i\n", i[0]);
        i[0] = i[0]+1;
        printf("C: i = %i\n", i[0]);
    }

Compile it with gcc -shared -fPIC plusOne.c -o plusOne.dll (or .so on Linux) and run in Julia:

    julia> i = Int32(42)
    42
    julia> ccall((:plusOne, "plusOne.dll"), Cvoid, (Ref{Cint},),i)
    C: i = 42
    C: i = 43
    julia> println("Julia: i = $i")
    Julia: i = 42

What is the correct way to use such C functions from Julia? The Julia documentation has examples for ccall (https://docs.julialang.org/en/v1/manual/calling-c-and-fortran-code/index.html), but always with arrays as returned data.

Of course I could also declare my i as an array of size 1. Then everything is working as expected.

like image 683
AnHeuermann Avatar asked Oct 27 '22 20:10

AnHeuermann


1 Answers

Int32(42) is not a reference type in Julia, and that's why you cannot update the value in the C function.

If you need to modify a Julia value, you need to change or wrap it in a reference type. You can use Array as you already know, but a more usual way would be wrapping it by Ref. So, try initializing i with Ref(Int32(42)). You can dereference the value with i[].

like image 90
bicycle1885 Avatar answered Nov 15 '22 13:11

bicycle1885