# Working with @cfunction (and parametric types)

To make a package v0.7 deprecation warning free, i recently moved the cfunction s into the @cfunction syntax and got caught on

``````ERROR: LoadError: could not evaluate cfunction argument type (it might depend on a local variable)
``````

which seems to be correct, the cfunction is

``````get_stream_callback(T) = @cfunction write_to_stream_callback  Int32 (Ref{T}, Ptr{UInt8}, UInt32)
``````

with T from

``````function CairoPDFSurface(stream::T, w::Real, h::Real) where {T<:IO}
callback = get_stream_callback(T)
ptr = ccall((:cairo_pdf_surface_create_for_stream,_jl_libcairo), Ptr{Nothing},
(Ptr{Nothing}, Any, Float64, Float64), callback, stream, w, h)
CairoSurface(ptr, w, h)
end
``````

I understand, that the cfunction macro needs a concrete(?) type, but does this mean i have to rewrite the function - and drop the parametric type?

The only workaround I’m aware of is to make your function an `@generated` function so that it can produce literal types for `ccall`. For example:

``````@generated function foo(x::T) where T
quote
ccall(..., ..., (Ref{\$T},), x)
end
end
``````

Edit: sorry, wasn’t paying careful enough attention and mixed up my ccalls and cfunctions. The above is probably not correct.

Perhaps:

``````get_stream_callback(::Type{T}) where {T} = @cfunction write_to_stream_callback  Int32 (Ref{T}, Ptr{UInt8}, UInt32)
``````

btw: Thank you. There was a race condition as David Anthoff asked the same question also on slack … but the solution converged.

That shouldn’t be necessary for `ccall` either — the rules for `cfunction` for v0.7 are now largely brought in line with those for `ccall` from v0.6. In particular, Kristoffer’s solution is correct for both.