# Passing a local to @cfunction fails

**URL:** https://discourse.julialang.org/t/passing-a-local-to-cfunction-fails/40815
**Category:** General Usage
**Created:** [June 5, 2020, 2:53pm UTC](https://discourse.julialang.org/t/passing-a-local-to-cfunction-fails/40815 "2020-06-05T14:53:31Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![nabla](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nabla/32/26089_2.png) [@nabla](https://discourse.julialang.org/u/nabla)
#### Post date: [June 5, 2020, 2:53pm UTC](https://discourse.julialang.org/t/passing-a-local-to-cfunction-fails/40815/1 "2020-06-05T14:53:31Z")

</div>

I want to pass a local function via @cfunction to a library, but can’t do it. (This function is a callback, and should store some data as it’s called).

Minimal non-working example of what I would like:

```julia
const badlocaldata = Int[]
function badbar(i::Int)
    global badlocaldata
    push!(badlocaldata,i)
end

function foo()
    localdata = Int[]
    function bar(i::Int)
        push!(localdata,i)
    end

    # this fails with error message "UndefVarError: bar not defined"
    ccall(:libfunction,Cvoid,(Ptr{Cvoid},),@cfunction(bar,Nothing,(Int,))) 

    # this works, but uses a global so is not threadsafe (and it's super-inelegant)
    ccall(:libfunction,Cvoid,(Ptr{Cvoid},),@cfunction(badbar,Nothing,(Int,))) 
end

```

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [June 5, 2020, 4:23pm UTC](https://discourse.julialang.org/t/passing-a-local-to-cfunction-fails/40815/2 "2020-06-05T16:23:10Z")

</div>

> [@nabla](#):
>
> I want to pass a local function via @cfunction to a library, but can’t do it. (This function is a callback, and should store some data as it’s called).

As explained in the [`@cfunction` documentation](https://docs.julialang.org/en/latest/base/c/#Base.@cfunction), the `@cfunction` macro evaluates its arguments in global scope. If you want to use a local function, you need to interpolate it with `$`.

(It is more efficient to use a global function here. If you need to pass local data, a well-written C library should generally accept a `void*` to data in addition to the function library, to pass data re-entrantly through to the function pointer at the call site.)

---

<div class="post-metadata">

### Author: ![nabla](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nabla/32/26089_2.png) [@nabla](https://discourse.julialang.org/u/nabla)
#### Post date: [June 5, 2020, 7:30pm UTC](https://discourse.julialang.org/t/passing-a-local-to-cfunction-fails/40815/3 "2020-06-05T19:30:07Z")

</div>

Thanks a lot!

About your comment: yes… but isn’t that the whole point of Julia, to make use of not-so-well-written C libraries 😉 Good to know there’s a workaround.

---

<div class="post-metadata">

### Author: ![nabla](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nabla/32/26089_2.png) [@nabla](https://discourse.julialang.org/u/nabla)
#### Post date: [June 5, 2020, 7:50pm UTC](https://discourse.julialang.org/t/passing-a-local-to-cfunction-fails/40815/4 "2020-06-05T19:50:40Z")

</div>

Hi @stevengj,  
Sorry to reopen this… but I see that there’s a subtle difference between the @cfunction with and without $: the first one returns an struct Base.CFunction while the second returns a Ptr{Nothing}. Now Julia doesn’t know how to convert Base.CFunction to Ptr{Nothing}.

I see that that the CFunction struct has a field ptr, is it the one to use as the C callable function? I tried it and it seems to work (well, it didn’t sigsegv…).

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [June 5, 2020, 8:55pm UTC](https://discourse.julialang.org/t/passing-a-local-to-cfunction-fails/40815/5 "2020-06-05T20:55:34Z")

</div>

> [@nabla](#):
>
> Now Julia doesn’t know how to convert Base.CFunction to Ptr{Nothing}.

Yes it does, but only in the context of a `ccall` (which is the only place you’d generally want to perform this conversion). When you pass a `CFunction` for a `Ptr{Cvoid}` argument in a `ccall`, it calls the [`unsafe_convert`](https://docs.julialang.org/en/latest/manual/calling-c-and-fortran-code/#automatic-type-conversion-1) function, which [has a method for `CFunction`](https://github.com/JuliaLang/julia/blob/d825de85f89034bca81524b3def72f6237f08de0/base/c.jl#L36).

---

<div class="post-metadata">

### Author: ![nabla](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nabla/32/26089_2.png) [@nabla](https://discourse.julialang.org/u/nabla)
#### Post date: [June 6, 2020, 2:28pm UTC](https://discourse.julialang.org/t/passing-a-local-to-cfunction-fails/40815/6 "2020-06-06T14:28:26Z")

</div>

Ah, OK.  
In my situation, I don’t pass the C function directly to a library, but as a component in a C struct which itself is passed to the library function. I guess then that the unsafe\_convert should be as close as possible to the ccall, to guarantee no garbage collection in between?

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [June 6, 2020, 8:01pm UTC](https://discourse.julialang.org/t/passing-a-local-to-cfunction-fails/40815/7 "2020-06-06T20:01:59Z")

</div>

> [@nabla](#):
>
> I guess then that the unsafe\_convert should be as close as possible to the ccall, to guarantee no garbage collection in between?

No, you should use `GC.@preserve` on the `CFunction` object to prevent it from being garbage-collected for as long as you need the pointer.
