I want to do something like this, inside a begin block:
begin
f(x) = x * x
ptr = @cfunction(f, Cdouble, (Cdouble,))
g(x) = ccall(ptr, Cdouble, (Cdouble,), x)
g(1.2)
end
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), ...))?
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
(edited, see next comment for the correct solution)
julia> function f end
begin
global f
f(x) = x * x
ptr = @cfunction(f, Cdouble, (Cdouble,))
g(x) = ccall(ptr, Cdouble, (Cdouble,), x)
g(1.2)
end
1.44
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)
end
4.0