# Cfunction from 0.6 to 1.0

**URL:** <https://discourse.julialang.org/t/cfunction-from-0-6-to-1-0/28441>\
**Category:** General Usage\
**Tags:** question\
**Created:** [September 5, 2019, 7:45pm UTC](https://discourse.julialang.org/t/cfunction-from-0-6-to-1-0/28441 "2019-09-05T19:45:47Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)\
**Post date:** [September 5, 2019, 7:45pm UTC](https://discourse.julialang.org/t/cfunction-from-0-6-to-1-0/28441/1 "2019-09-05T19:45:47Z")

</div>

I am upgrading a package that wraps a C library from julia 0.6 to 1.0. In principle this should be very simple, but in practice I am running into some problems (naturally). In particular, migrating from 0.6 to 0.7 as an intermediate, I go from all tests passing to encountering a segfault early on from a `ccall`.

The following code is the segfault culprit in 0.7, but works in 0.6

```julia
# `functions` contains symbol pairs
for (name, C_name) in functions
    # define julia function with ccall
    @eval $name(mgr::Ptr{Manager}, f_pp::Ptr{Ptr{Node}}, g_pp::Ptr{Ptr{Node}}) =
                ccall(($(QuoteNode(C_name)), _LIB_CUDD),
                      Ptr{Node}, (Ptr{Manager}, Ptr{Ptr{Node}}, Ptr{Ptr{Node}}), mgr, f_pp, g_pp)
    # create c function pointer
    @eval $(Symbol(name, "_c")) = Compat.@cfunction($name, Ptr{Node}, (Ptr{Manager}, Ptr{Ptr{Node}}, Ptr{Ptr{Node}}))
end

```

What I have noticed in manually inspecting the pointers generated by the second `@eval` is that in 0.6 they are each unique, while in 0.7 they are all `Ptr{Nothing} @0x0000000000000000`. I assumed using `Compat.@cfunction` would be all that was necessary to migrate this code, but it appears not. If anyone knows what is missing / what is going on, I’d appreciate the input!

---

<div class="post-metadata">

**Author:** ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)\
**Post date:** [September 5, 2019, 8:02pm UTC](https://discourse.julialang.org/t/cfunction-from-0-6-to-1-0/28441/2 "2019-09-05T20:02:27Z")

</div>

For reference (and ease of reading), here is one function in `functions` written out explicitly instead of using `@eval`.

```julia
function add_plus(mgr::Ptr{Manager}, f_pp::Ptr{Ptr{Node}}, g_pp::Ptr{Ptr{Node}})
    func = ccall((:Cudd_addPlus, _LIB_CUDD),
        Ptr{Node}, (Ptr{Manager}, Ptr{Ptr{Node}}, Ptr{Ptr{Node}}), mgr, f_pp, g_pp)
    return func
end
add_plus_c = Compat.@cfunction(add_plus, Ptr{Node}, (Ptr{Manager}, Ptr{Ptr{Node}}, Ptr{Ptr{Node}}))

```

---

<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:** [September 5, 2019, 8:16pm UTC](https://discourse.julialang.org/t/cfunction-from-0-6-to-1-0/28441/3 "2019-09-05T20:16:56Z")

</div>

> [@tomerarnon](#):
>
> here is one function in `functions` written out explicitly instead of using `@eval` .

Seems to work fine for me in both Julia 0.7 and Julia 1.2 (using dummy definitions `struct Manager; end` and `struct Node; end`) and removing the `Compat.` in Julia 1.2. At least, I’m getting a non-NULL pointer back.

---

<div class="post-metadata">

**Author:** ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)\
**Post date:** [September 5, 2019, 8:24pm UTC](https://discourse.julialang.org/t/cfunction-from-0-6-to-1-0/28441/4 "2019-09-05T20:24:42Z")

</div>

> Seems to work fine for me

Fair enough! Turns out the null pointers were from when I was looking at 1.0, and in 0.7 they are indeed valid. That said, I see the segfault in both 0.7 and 1.0. I haven’t tried in 1.2 (or 1.1 for that matter) but I’ll give that a go as well.

I also forgot a potentially crucial piece of information. All of the functions defined in @eval are actually called inside yet another ccall:

```julia
function add_apply(mgr::Ptr{Manager}, op, f::Ptr{Node}, g::Ptr{Node})
    res = ccall((:Cudd_addApply, _LIB_CUDD),
        Ptr{Node}, (Ptr{Manager}, Ptr{Cvoid}, Ptr{Node}, Ptr{Node}), mgr, op, f, g)
    if res == C_NULL # Fails to compute a result
        throw(OutOfMemoryError())
    end
    return res
end

```

So the call that segfaults ultimately looks like `add_apply(manager, add_plus_c, f, g)`

EDIT:  
Segfaulted also in 1.2.  
Also, I’m noticing now that the pointers in _all_ versions of julia are unique _if_ the code above is run at the terminal (and also if using @show at the point they are defined). Inspecting the value of the pointer in the module after `using` it, show it is null however. Any ideas @stevengj?

---

<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:** [September 5, 2019, 9:36pm UTC](https://discourse.julialang.org/t/cfunction-from-0-6-to-1-0/28441/5 "2019-09-05T21:36:27Z")

</div>

Precompilation of modules is off by default in Julia v0.6 and on by default in v0.7 and above. In addition, any pointers in global variables are set to null during precompilation to avoid baking in pointers to arbitrary memory addresses (which will be completely different when the precompiled module is loaded later on).

It seems like your module is not safe for precompilation, which is causing the problem you’re seeing. Rather than trying to construct `cfunction`s as global variables in your module, you should be able to use the `const Ref` trick, e.g.:

```julia
module Foo

const add_plus_c = Ref{<fill this in>}()

function __init__ ()
  add_plus_c[] = @cfunction(...)
end

end

```

For more on precompilation, see: [Modules · The Julia Language](https://docs.julialang.org/en/v1/manual/modules/index.html#Module-initialization-and-precompilation-1)

---

<div class="post-metadata">

**Author:** ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)\
**Post date:** [September 5, 2019, 9:48pm UTC](https://discourse.julialang.org/t/cfunction-from-0-6-to-1-0/28441/6 "2019-09-05T21:48:46Z")

</div>

Thanks @rdeits! I didn’t know that about precompilation, but that seems like a likely culprit. I’ll try the Ref trick.

Edit: setting ` __precompile__ (false)` gets past the tests, so I’d say this may well be solved!

---

<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:** [September 5, 2019, 10:01pm UTC](https://discourse.julialang.org/t/cfunction-from-0-6-to-1-0/28441/7 "2019-09-05T22:01:19Z")

</div>

Yeah, turning off precompilation will avoid the issue, but note that it means that no package which depends on your package can be precompiled either, which may be annoying. Using a `const Ref`, on the other hand, will let you and any downstream users benefit from precompilation.

---

<div class="post-metadata">

**Author:** ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)\
**Post date:** [September 5, 2019, 10:07pm UTC](https://discourse.julialang.org/t/cfunction-from-0-6-to-1-0/28441/8 "2019-09-05T22:07:08Z")

</div>

Indeed, I’ll go through with the `const Ref` change as well. Thanks again @rdeits.

---

<div class="post-metadata">

**Author:** ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)\
**Post date:** [September 5, 2019, 10:11pm UTC](https://discourse.julialang.org/t/cfunction-from-0-6-to-1-0/28441/9 "2019-09-05T22:11:34Z")

</div>

Just to clarify what goes in `Ref{<fill this in>}`, should it be `Ptr{Nothing}` since that’s what the @cfunction returns?

---

<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:** [September 5, 2019, 10:13pm UTC](https://discourse.julialang.org/t/cfunction-from-0-6-to-1-0/28441/10 "2019-09-05T22:13:13Z")

</div>

Yup, exactly

---

<div class="post-metadata">

**Author:** ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)\
**Post date:** [September 5, 2019, 10:28pm UTC](https://discourse.julialang.org/t/cfunction-from-0-6-to-1-0/28441/11 "2019-09-05T22:28:55Z")

</div>

I hate to return bearing bad news, but using `Ref`s leads to a different issue. The pointers are now all valid, but running the tests still fails, this time with “Bus error: 10” rather than a segfault.

Not sure if it matters, but I’m defining and filling the Refs in a loop as before, with ` __init__ ()` looking as follows (could probably be written much simpler, but oh well)

```julia

function __init__ ()
    for (name, _) in functions
        @eval $(Symbol(name, "_c"))[] = Compat.@cfunction($name, Ptr{Node}, (Ptr{Manager}, Ptr{Ptr{Node}}, Ptr{Ptr{Node}}))
    end
end

```

I also tried defining a few the explicit way and saw the same result.

---

<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:** [September 6, 2019, 12:58am UTC](https://discourse.julialang.org/t/cfunction-from-0-6-to-1-0/28441/12 "2019-09-06T00:58:37Z")

</div>

I’m not sure what’s going on there. One thing to note is that if you are using a Ref `foo` to hold your cfunction, then you need to be sure to replace all the usages of `foo` with `foo[]`. Have you already done that?

---

<div class="post-metadata">

**Author:** ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)\
**Post date:** [September 6, 2019, 1:12am UTC](https://discourse.julialang.org/t/cfunction-from-0-6-to-1-0/28441/13 "2019-09-06T01:12:28Z")

</div>

I hadn’t! I remembered reading something about how the Ref was converted into a pointer automatically in the `ccall`…?  
Not sure why I thought that, and in any case I guess that wouldn’t even be what I want.

Anyway, everything works now. Thanks a lot for all the help!

---

<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:** [September 6, 2019, 2:31pm UTC](https://discourse.julialang.org/t/cfunction-from-0-6-to-1-0/28441/14 "2019-09-06T14:31:17Z")

</div>

You’re right–a Ref will get converted into a pointer, but in this case it’s going to be a pointer _to_ the function pointer, not the function pointer itself (the Ref essentially adds one more layer of indirection).
