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, but still when I try to call the Julia function in C, I got segmentation fault.
My Julia code is:
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:
#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:
gcc sampleProgram.c -o sampleProgram
gcc -shared -o sampleProgram.so -fPIC sampleProgram.c
julia sampleProgram.jl
Thank you for your help.