# @cfunction and generated functions

**URL:** https://discourse.julialang.org/t/cfunction-and-generated-functions/13265
**Category:** General Usage
**Created:** [August 11, 2018, 8:23pm UTC](https://discourse.julialang.org/t/cfunction-and-generated-functions/13265 "2018-08-11T20:23:46Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)
#### Post date: [August 11, 2018, 8:23pm UTC](https://discourse.julialang.org/t/cfunction-and-generated-functions/13265/1 "2018-08-11T20:23:46Z")

</div>

With the new [`@cfunction` macro](https://docs.julialang.org/en/latest/base/c/#Base.@cfunction), there is now the option to use `$` syntax to create a runtime closure over a callable, which (I think, please correct me if this is wrong) can be safely used as follows:

```julia
cfun = @cfunction $identity Int (Int,) # a CFunction
GC.@preserve cfun begin
    ptr = Base.unsafe_convert(Ptr{Cvoid}, Base.cconvert(Ptr{Cvoid}, cfun))
    ccall(ptr, Int, (Int,), 42)
end

```

So far so good, but now I’m trying to write a generated function that uses `@cfunction`. Here are two attempts:

```julia
@generated function makefun1(obj)
    quote
        @cfunction $obj Int (Int,)
    end
end
cfun = makefun1(identity) # a Ptr{Cvoid}, not a CFunction!

```

```julia
@generated function makefun2(obj)
    quote
        @cfunction $(Expr(:$, obj)) Int (Int,)
    end
end
cfun = makefun2(identity) # a CFunction, so far so good
GC.@preserve cfun begin
    ptr = Base.unsafe_convert(Ptr{Cvoid}, Base.cconvert(Ptr{Cvoid}, cfun))
    ccall(ptr, Int, (Int,), 42) # error!
end

```

The error I get with this last version is:

```julia
ERROR: MethodError: Cannot `convert` an object of type Int64 to an object of type typeof(identity)
Closest candidates are:
  convert(::Type{T}, ::T) where T at essentials.jl:154
Stacktrace:
 [1] typeof(identity)(::Int64) at ./deprecated.jl:473
 [2] top-level scope at ./gcutils.jl:87

```

which happens because the _type_ of `obj` gets interpolated in the generated function.

How do I do this? I guess I’m just confused due to the two different meanings of `$`.

(Note: the application is FunctionWrappers.jl; my [PR for 1.0 support](https://github.com/yuyichao/FunctionWrappers.jl/pull/7) currently passes tests but just reimplements the old `jl_function_ptr` call that was present in `cfunction` on 0.6. I’m trying to get [this part](https://github.com/tkoolen/FunctionWrappers.jl/blob/2ff7665134c35f7bb5057fd3557371e88fef8764/src/FunctionWrappers.jl#L37-L42) working (@rdeits’ branch).

---

<div class="post-metadata">

### Author: ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)
#### Post date: [August 11, 2018, 8:33pm UTC](https://discourse.julialang.org/t/cfunction-and-generated-functions/13265/2 "2018-08-11T20:33:02Z")

</div>

As any other metaprogramming, check the expression you are generating.

`Expr(:$, :obj)`.

---

<div class="post-metadata">

### Author: ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)
#### Post date: [August 11, 2018, 8:36pm UTC](https://discourse.julialang.org/t/cfunction-and-generated-functions/13265/3 "2018-08-11T20:36:27Z")

</div>

Ah OK, that wasn’t as hard as I thought it was.

---

<div class="post-metadata">

### Author: ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)
#### Post date: [August 11, 2018, 8:56pm UTC](https://discourse.julialang.org/t/cfunction-and-generated-functions/13265/4 "2018-08-11T20:56:45Z")

</div>

@yuyichao, what do you think about `CallWrapper` in 1.0? `@cfunction` is now capable of handling closures and that was one of `CallWrapper`’s purposes (the other being conversion to the desired return type). I was thinking about simply turning `CallWrapper` into

```julia
struct CallWrapper{Ret, F}
    f::F
end

CallWrapper{Ret}(f::F) where {Ret, F} = CallWrapper{Ret, F}(f)

(wrapper::CallWrapper{Ret})(args...) where {Ret} = convert(Ret, wrapper.f(args...))

for nargs in 0:128
    @eval function (wrapper::CallWrapper{Ret})($((Symbol("arg", i) for i in 1:nargs)...)) where Ret
        convert(Ret, wrapper.f($((Symbol("arg", i) for i in 1:nargs)...)))
    end
end

```

Thoughts?

---

<div class="post-metadata">

### Author: ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)
#### Post date: [August 11, 2018, 9:14pm UTC](https://discourse.julialang.org/t/cfunction-and-generated-functions/13265/5 "2018-08-11T21:14:42Z")

</div>

Well, I got it working on 0.7 with `@cfunction` and the approach I described in my previous post. Probably easier to discuss over at [Fixes for Julia 0.7. Drop 0.5 and 0.6. by tkoolen · Pull Request #7 · yuyichao/FunctionWrappers.jl · GitHub](https://github.com/yuyichao/FunctionWrappers.jl/pull/7).
