Calling Julia Functions using 'cfunction'

Hello,

Besides the examples given in doc (https://docs.julialang.org/en/stable/manual/embedding/), I figured out two more methods to call Julia functions in C, using the built-in ‘cfunction’:

1)  use julia cfunction
    typedef float (*Func)(float);
    jl_value_t *ret = jl_eval_string("cfunction(sqrt, Cfloat, (Cfloat,))"); 
    JL_GC_PUSH1(&ret);
    void *ptr1 = jl_unbox_voidpointer(ret); 
    Func csqrt = (Func)ptr1;
    float r40 = csqrt(2.0f); 
    printf("%f", r40);
    JL_GC_POP();
2) use jl_function_ptr. this is the function called by 'cfunction' in base/c.jl. It's not provided in Julia.h, just put it somewhere.  

JL_DLLEXPORT void *jl_function_ptr(jl_function_t *f, jl_value_t *rt, jl_value_t *argt);

    typedef float (*Func)(float);
    jl_function_t *f = jl_get_function(jl_base_module, "sqrt");
    jl_value_t *rt = jl_eval_string("Cfloat");
    jl_value_t *argt = jl_eval_string("(Cfloat,)"); 
    JL_GC_PUSH3(&f, &rt, &argt);
    void *ptr = jl_function_ptr(f, rt, argt); 
    Func csqrt = (Func)ptr; 
    float r30 = csqrt(2.0f); 
    JL_GC_POP();

It works on x86_64-w64-mingw32 with Julia 0.6.2 pre-built binaries. Other platforms not tested.
Note : JL_GC_PUSH* introduced an undefined reference to __imp_jl_tls_states with the 0.6.2 Win64 binaries.

#define JULIA_ENABLE_THREADING 0

to work around.

Hope this info is helpful.

Regards,
pem

4 Likes