Using a Base.CFunction in ccall


I want to do something like this, inside a begin block:

    f(x) = x * x
    ptr = @cfunction(f, Cdouble, (Cdouble,))
    g(x) = ccall(ptr, Cdouble, (Cdouble,), x)

However this gives the following error:

ERROR: LoadError: UndefVarError: f not defined

I’ve been suggested by @kristoffer.carlsson to use $f in @cfunction, thus resulting in the creation of Base.CFunction. However, I don’t understand ho to use in a ccall. I couldn’t find any such example in Julia’s Base. Base.CFunction's docstring reads:

Like all cfunction handles, it should be passed to ccall as a Ptr{Cvoid}, and will be converted automatically at the call site to the appropriate type.

How to convert a Base.CFunction to Ptr{Cvoid}? convert and Base.cconvert don’t work, but Base.unsafe_convert may do the trick. Is this the way to go (i.e., ccall(Base.unsafe_convert(Ptr{Cvoid}, ptr), ...))?


Does anyone have a clue about how to do this?


Is there some problem due to be inside the begin end block?
Anyway, just to confirm, are you aware of the qsort example, right?


Yes, I need to do this inside a begin-end block, specifically it’s in a @testset.

Yes, I know that example and I’ve used callbacks in Cuba.jl. However, here there is no callback, I just want to ccall a very simple function defined with @cfunction


Oh, that’s true, I had not read your original question very carefully.


Bump. Does anyone know how to do this?

(edited, see next comment for the correct solution)
julia> function f end
           global f
           f(x) = x * x
           ptr = @cfunction(f, Cdouble, (Cdouble,))
           g(x) = ccall(ptr, Cdouble, (Cdouble,), x)


No that’s not a closure (If you don’t need a closure then that’s fine but in that case you should use function f end instead of defining a dummy method).

julia> let f = (x)->x * x
           ptr = @cfunction $f Cdouble (Cdouble,)
           GC.@preserve ptr ccall(Base.unsafe_convert(Ptr{Cvoid}, ptr), Cdouble, (Cdouble,), 2.0)


Ok, so Base.unsafe_convert was indeed the way to go, I was missing the GC.@preserve. Thank you!


This topic was automatically closed 12 days after the last reply. New replies are no longer allowed.