# Passing a Julia function to C and then calling from C code

**URL:** <https://discourse.julialang.org/t/passing-a-julia-function-to-c-and-then-calling-from-c-code/82217>\
**Category:** General Usage\
**Tags:** question, embedding, c\
**Created:** [June 3, 2022, 11:39pm UTC](https://discourse.julialang.org/t/passing-a-julia-function-to-c-and-then-calling-from-c-code/82217 "2022-06-03T23:39:18Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Fadi\_Hamad](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fadi_hamad/32/36897_2.png) [@Fadi\_Hamad](https://discourse.julialang.org/u/Fadi_Hamad)\
**Post date:** [June 3, 2022, 11:39pm UTC](https://discourse.julialang.org/t/passing-a-julia-function-to-c-and-then-calling-from-c-code/82217/1 "2022-06-03T23:39:18Z")

</div>

Hello,

I am trying to pass a Julia function to a some C code and then call that Julia function from within my C code. I followed the instruction from the section [https://docs.julialang.org/en/v1/manual/calling-c-and-fortran-code/#Creating-C-Compatible-Julia-Function-Pointers](https://docs.julialang.org/en/v1/manual/calling-c-and-fortran-code/#Creating-C-Compatible-Julia-Function-Pointers), but still when I try to call the Julia function in C, I got segmentation fault.

My Julia code is:

```julia
function mycompare(a)::Cint
    return 2 * a
end

function mycompare2(a, b)::Cint
    return (a < b) ? -1 : ((a > b) ? +1 : 0)
end

struct my_userdata_type_c
    n::Cint
    func::Ptr{Cvoid}
end

struct my_userdata_type_2_c
    p::Cdouble
end

function main()
    cd("/home/fah33/Test_C_Julia")
    A = [1.3, -2.7, 4.4, 3.1]
    @show A
    mycompare_c2 = @cfunction(mycompare2, Cint, (Ref{Cdouble},Ref{Cdouble}));
    ccall(:qsort, Cvoid, (Ptr{Cdouble}, Csize_t, Csize_t, Ptr{Cvoid}),
             A, length(A), sizeof(eltype(A)), mycompare_c2)
    @show A
    A = [1.3, -2.7, 4.4, 3.1]
    @show A
    struct_test_1 = my_userdata_type_c(100, mycompare_c2)
    ccall(:qsort, Cvoid, (Ptr{Cdouble}, Csize_t, Csize_t, Ptr{Cvoid}),
             A, length(A), sizeof(eltype(A)), struct_test_1.func)
    @show A
    mycompare_c = @cfunction(mycompare, Cint, (Ref{Cint},));
    @show ccall((:compare, "/home/fah33/Test_C_Julia/sampleProgram.so"), Int64, (Cint,), 4)
    @show ccall((:compare, "/home/fah33/Test_C_Julia/sampleProgram.so"), Int64, (Cint,), 3)
    #@show ccall((:eval_f, "/home/fah33/Test_C_Julia/sampleProgram.so"), Int64, (Cint, Ptr{Cvoid}), 1000, mycompare_c)
    struct_test_2 = my_userdata_type_2_c(3.0)
    @show ccall((:testFct2, "/home/fah33/Test_C_Julia/sampleProgram.so"), Int64, (Ref{my_userdata_type_2_c},), struct_test_2)
    @show struct_test_2.p
    struct_test = my_userdata_type_c(100, mycompare_c)
    @show struct_test
    #@show ccall((:testFct, "/home/fah33/Test_C_Julia/sampleProgram.so"), Int64, (my_userdata_type_c,), struct_test)
end

main()

```

My C code is:

```julia
#include<stdio.h>

int compare(int n){
    return n;
}

struct userdata_type {
    int n;
    int (*function)(int n);
};

int testFct(struct userdata_type user){
    printf("\n!testFct\n\n");
    printf("%d\n", user.n);
    return (*user.function)(user.n);
}

struct userdata_type2 {
    double p;
};

double testFct2(struct userdata_type2 user){
    printf("\ntestFct2\n\n");
    printf("%f\n", user.p);
    user.p = 2 * user.p;
    return user.p;
}

int function_test(int x){
    return x;
}

int eval_f(int n, int (*f)(int)){
    printf("\neval_f\n\n");
    printf("%d\n", (*f)(n));
    return 0;
}

int main()
{
    printf("\nA sample C program\n\n");
    struct userdata_type userdata;
    userdata.n = 1;
    userdata.function = compare;
    printf("%d\n", userdata.n);
    printf("%d\n", userdata.function(1));
    printf("%d\n", eval_f(20000, function_test));
    printf("\nA sample C program\n\n");
    return 0;
}

```

When I uncomment calling eval\_f or testFct, I got Segmentation fault with an error stating unknown function.

The commands I use to run my code are:

```julia
gcc sampleProgram.c -o sampleProgram
gcc -shared -o sampleProgram.so -fPIC sampleProgram.c
julia sampleProgram.jl

```

Thank you for your help.

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [June 4, 2022, 8:41am UTC](https://discourse.julialang.org/t/passing-a-julia-function-to-c-and-then-calling-from-c-code/82217/3 "2022-06-04T08:41:20Z")

</div>

You can think of `Ref{Cint}` as `int *`.

The following C and Julia code work together.

```nohighlight
#include<stdio.h>

int compare(int *n){
    return *n;
}

struct userdata_type {
    int n;
    int (*function)(int * n);
};

int testFct(struct userdata_type user){
    printf("\n!testFct\n\n");
    printf("%d\n", user.n);
    return (*user.function)(&(user.n));
}

struct userdata_type2 {
    double p;
};

double testFct2(struct userdata_type2 user){
    printf("\ntestFct2\n\n");
    printf("%f\n", user.p);
    user.p = 2 * user.p;
    return user.p;
}

int function_test(int* x){
    return *x;
}

int eval_f(int n, int (*f)(int*)){
    printf("\neval_f\n\n");
    printf("%d\n", (*f)(&n));
    return 0;
}

int main()
{
    printf("\nA sample C program\n\n");
    struct userdata_type userdata;
    userdata.n = 1;
    userdata.function = compare;
    printf("%d\n", userdata.n);
    int x = 1;
    printf("%d\n", userdata.function(&x));
    printf("%d\n", eval_f(20000, function_test));
    printf("\nA sample C program\n\n");
    return 0;
}

```

```julia
function mycompare(a)::Cint
    return 2 * a
end

function mycompare2(a, b)::Cint
    return (a < b) ? -1 : ((a > b) ? +1 : 0)
end

struct my_userdata_type_c
    n::Cint
    func::Ptr{Cvoid}
end

struct my_userdata_type_2_c
    p::Cdouble
end

function main()
    #cd("/home/fah33/Test_C_Julia")
    A = [1.3, -2.7, 4.4, 3.1]
    @show A
    mycompare_c2 = @cfunction(mycompare2, Cint, (Ref{Cdouble},Ref{Cdouble}));
    ccall(:qsort, Cvoid, (Ptr{Cdouble}, Csize_t, Csize_t, Ptr{Cvoid}),
             A, length(A), sizeof(eltype(A)), mycompare_c2)
    @show A
    A = [1.3, -2.7, 4.4, 3.1]
    @show A
    struct_test_1 = my_userdata_type_c(100, mycompare_c2)
    ccall(:qsort, Cvoid, (Ptr{Cdouble}, Csize_t, Csize_t, Ptr{Cvoid}),
             A, length(A), sizeof(eltype(A)), struct_test_1.func)
    @show A
    mycompare_c = @cfunction(mycompare, Cint, (Ref{Cint},));
    @show ccall((:compare, "./sampleProgram.so"), Int64, (Ref{Cint},), 4)
    @show ccall((:compare, "./sampleProgram.so"), Int64, (Ref{Cint},), 3)
    @show ccall(mycompare_c, Cint, (Ref{Cint},), 10)
    @show ccall((:eval_f, "./sampleProgram.so"), Int64, (Cint, Ptr{Cvoid}), 1000, mycompare_c)
    struct_test_2 = my_userdata_type_2_c(3.0)
    @show ccall((:testFct2, "./sampleProgram.so"), Int64, (Ref{my_userdata_type_2_c},), struct_test_2)
    @show struct_test_2.p
    struct_test = my_userdata_type_c(100, mycompare_c)
    @show struct_test
    @show ccall((:testFct, "./sampleProgram.so"), Int64, (my_userdata_type_c,), struct_test)
end

main()

```

I get the following output:

```julia
$ julia sampleProgram.jl
A = [1.3, -2.7, 4.4, 3.1]
A = [-2.7, 1.3, 3.1, 4.4]
A = [1.3, -2.7, 4.4, 3.1]
A = [-2.7, 1.3, 3.1, 4.4]
ccall((:compare, "./sampleProgram.so"), Int64, (Ref{Cint},), 4) = 4
ccall((:compare, "./sampleProgram.so"), Int64, (Ref{Cint},), 3) = 3
ccall(mycompare_c, Cint, (Ref{Cint},), 10) = 20

eval_f

2000
ccall((:eval_f, "./sampleProgram.so"), Int64, (Cint, Ptr{Cvoid}), 1000, mycompare_c) = 0

testFct2

0.000000
ccall((:testFct2, "./sampleProgram.so"), Int64, (Ref{my_userdata_type_2_c},), struct_test_2) = 0
struct_test_2.p = 3.0
struct_test = my_userdata_type_c(100, Ptr{Nothing} @0x00007f8995ae9ee0)

!testFct

100
ccall((:testFct, "./sampleProgram.so"), Int64, (my_userdata_type_c,), struct_test) = 200

```

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [June 4, 2022, 8:57am UTC](https://discourse.julialang.org/t/passing-a-julia-function-to-c-and-then-calling-from-c-code/82217/4 "2022-06-04T08:57:16Z")

</div>

Let’s say we kept your original C:

```nohighlight
struct userdata_type3 {
    int n;
    int (*function)(int n);
};

int testFct3(struct userdata_type3 user){
    printf("\n!testFct3\n\n");
    printf("%d\n", user.n);
    return (*user.function)(user.n);
}

```

We can then alter the Julia code to match:

```julia
    mycompare_c_noref = @cfunction(mycompare, Cint, (Cint,))
    @show ccall(mycompare_c_noref, Cint, (Cint,), 5)
    struct_test2 = my_userdata_type_c(300, mycompare_c_noref)
    @show ccall((:testFct3, "./sampleProgram.so"), Cint, (my_userdata_type_c,), struct_test2)

```

I then get the following output:

```julia
ccall(mycompare_c_noref, Cint, (Cint,), 5) = 10

!testFct3

300
ccall((:testFct3, "./sampleProgram.so"), Cint, (my_userdata_type_c,), struct_test2) = 600

```

The confusing thing is that Julia’s `@cfunction` will automatically dereference `Ref{Int}` to `Int` when passing the value to a Julia function.

---

<div class="post-metadata">

**Author:** ![Fadi\_Hamad](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fadi_hamad/32/36897_2.png) [@Fadi\_Hamad](https://discourse.julialang.org/u/Fadi_Hamad)\
**Post date:** [June 4, 2022, 12:52pm UTC](https://discourse.julialang.org/t/passing-a-julia-function-to-c-and-then-calling-from-c-code/82217/5 "2022-06-04T12:52:30Z")

</div>

Thank you for the help and clarifying this.
