# Working with @cfunction (and parametric types)

**URL:** <https://discourse.julialang.org/t/working-with-cfunction-and-parametric-types/12915>\
**Category:** General Usage\
**Tags:** question\
**Created:** [August 5, 2018, 1:18pm UTC](https://discourse.julialang.org/t/working-with-cfunction-and-parametric-types/12915 "2018-08-05T13:18:35Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![lobingera](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lobingera/32/211_2.png) [@lobingera](https://discourse.julialang.org/u/lobingera)\
**Post date:** [August 5, 2018, 1:18pm UTC](https://discourse.julialang.org/t/working-with-cfunction-and-parametric-types/12915/1 "2018-08-05T13:18:35Z")

</div>

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

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

```

which seems to be correct, the cfunction is

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

```

with T from

```julia
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?

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [August 6, 2018, 3:17pm UTC](https://discourse.julialang.org/t/working-with-cfunction-and-parametric-types/12915/2 "2018-08-06T15:17:38Z")

</div>

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:

```julia
@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.

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [August 6, 2018, 3:44pm UTC](https://discourse.julialang.org/t/working-with-cfunction-and-parametric-types/12915/3 "2018-08-06T15:44:02Z")

</div>

Perhaps:

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

```

---

<div class="post-metadata">

**Author:** ![lobingera](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lobingera/32/211_2.png) [@lobingera](https://discourse.julialang.org/u/lobingera)\
**Post date:** [August 7, 2018, 12:23pm UTC](https://discourse.julialang.org/t/working-with-cfunction-and-parametric-types/12915/4 "2018-08-07T12:23:32Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![jameson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jameson/32/23_2.png) [@jameson](https://discourse.julialang.org/u/jameson)\
**Post date:** [August 7, 2018, 4:11pm UTC](https://discourse.julialang.org/t/working-with-cfunction-and-parametric-types/12915/5 "2018-08-07T16:11:11Z")

</div>

> [@rdeits](#):
>
> The only workaround I’m aware of is to make your function an `@generated` function so that it can produce literal types for `ccall`

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.
