# Null function pointer in a function creaded with @eval

**URL:** https://discourse.julialang.org/t/null-function-pointer-in-a-function-creaded-with-eval/13202
**Category:** General Usage
**Created:** [August 10, 2018, 8:44pm UTC](https://discourse.julialang.org/t/null-function-pointer-in-a-function-creaded-with-eval/13202 "2018-08-10T20:44:54Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![yutaka](https://avatars.discourse-cdn.com/v4/letter/y/dc4da7/32.png) [@yutaka](https://discourse.julialang.org/u/yutaka)
#### Post date: [August 10, 2018, 8:44pm UTC](https://discourse.julialang.org/t/null-function-pointer-in-a-function-creaded-with-eval/13202/1 "2018-08-10T20:44:54Z")

</div>

I am trying to modify [AMD.jl](https://github.com/JuliaSmoothOptimizers/AMD.jl) to support Julia 0.7.0. This is a wrapper package to call C functions using `ccall`. The function pointers are defined as follows.

```julia
global const _libamd = Libdl.dlopen("libamd")
global const _amd_valid = Libdl.dlsym(_libamd, "amd_valid")
global const _amd_l_valid = Libdl.dlsym(_libamd, "amd_l_valid")

```

A main function `amd_valid` is defined with `@eval` to support different types.

```julia
for (validfn, typ) in ((_amd_valid, Cint), (_amd_l_valid, Clong))
  @eval begin
    function amd_valid(A :: SparseMatrixCSC{F,$typ}) where F
      nrow = $typ(size(A,1))
      ncol = $typ(size(A,2))
      colptr = A.colptr .- $typ(1) # 0-based indexing
      rowval = A.rowval .- $typ(1)
      valid = ccall($validfn, $typ,
                    ($typ, $typ, Ptr{$typ}, Ptr{$typ}), nrow, ncol, colptr, rowval)
      return valid == AMD_OK || valid == AMD_OK_BUT_JUMBLED
    end
  end
end

```

Running a test, I got an error `ERROR: LoadError: ccall: null function pointer`. This function perfectly worked in Julia 0.6.0. When I replaced `$validfn` with `Libdl.dlsym(Libdl.dlopen("libamd"), "amd_valid")`, the function works without the error. It looks straightforward but a bit redundant.

What is the best way to modify this function? And if possible, please let me know why Julia 0.7 does not accept $validfn.

---

<div class="post-metadata">

### Author: ![dpo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpo/32/3335_2.png) [@dpo](https://discourse.julialang.org/u/dpo)
#### Post date: [August 14, 2018, 3:53pm UTC](https://discourse.julialang.org/t/null-function-pointer-in-a-function-creaded-with-eval/13202/2 "2018-08-14T15:53:20Z")

</div>

Thanks for looking into this. I wrote AMD.jl and I’m stuck at the same place. I thought the issue might be related to [https://github.com/JuliaLang/julia/issues/26557#issuecomment-374963443](https://github.com/JuliaLang/julia/issues/26557#issuecomment-374963443) but writing a BinDeps script to download and build the libamd from SuiteSparse led to the same error message.

@kristoffer.carlsson Any ideas?

---

<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 14, 2018, 3:54pm UTC](https://discourse.julialang.org/t/null-function-pointer-in-a-function-creaded-with-eval/13202/3 "2018-08-14T15:54:52Z")

</div>

That’s the point where I left [https://github.com/JuliaSparse/Pardiso.jl/pull/36](https://github.com/JuliaSparse/Pardiso.jl/pull/36) yesterday 😉

Not sure what the solution is.

---

<div class="post-metadata">

### Author: ![dpo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpo/32/3335_2.png) [@dpo](https://discourse.julialang.org/u/dpo)
#### Post date: [August 14, 2018, 4:54pm UTC](https://discourse.julialang.org/t/null-function-pointer-in-a-function-creaded-with-eval/13202/4 "2018-08-14T16:54:05Z")

</div>

Pasting the same code at the REPL does work though:

```julia
julia> libamd = "/Users/dpo/.julia/packages/AMD/k9NUS/deps/usr/lib/libamd.dylib";
julia> global const _libamd = Libdl.dlopen(libamd)
Ptr{Nothing} @0x00007fd7c4c136e0

julia> global const _amd_valid = Libdl.dlsym(_libamd, "amd_valid")
Ptr{Nothing} @0x00000001249ef020

julia> global const _amd_l_valid = Libdl.dlsym(_libamd, "amd_l_valid")
Ptr{Nothing} @0x00000001249f2ff0

julia> for (validfn, typ) in ((_amd_valid, Cint), (_amd_l_valid, Clong))
         @eval begin
           function amd_valid(A :: SparseMatrixCSC{F,$typ}) where F
             nrow, ncol = size(A)
             colptr = A.colptr .- $typ(1) # 0-based indexing
             rowval = A.rowval .- $typ(1)
             valid = ccall($validfn, $typ,
                           ($typ, $typ, Ptr{$typ}, Ptr{$typ}), nrow, ncol, colptr, rowval)
             return valid == AMD_OK || valid == AMD_OK_BUT_JUMBLED
           end 
         end 
       end

julia> const AMD_OK = 0; # success
julia> const AMD_OK_BUT_JUMBLED = 1; # input ok but AMD will need to perform extra work
julia> amd_valid(sparse(rand(10,10)))
true

julia> amd_valid(convert(SparseMatrixCSC{Float64, Clong}, sparse(rand(10,10))))
true

```

---

<div class="post-metadata">

### Author: ![dpo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpo/32/3335_2.png) [@dpo](https://discourse.julialang.org/u/dpo)
#### Post date: [August 17, 2018, 12:47pm UTC](https://discourse.julialang.org/t/null-function-pointer-in-a-function-creaded-with-eval/13202/5 "2018-08-17T12:47:54Z")

</div>

One solution appears to be to enclose the library and symbols definitions in the module’s ` __init__ `. At least, that worked for AMD.jl.

---

<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 17, 2018, 12:55pm UTC](https://discourse.julialang.org/t/null-function-pointer-in-a-function-creaded-with-eval/13202/6 "2018-08-17T12:55:50Z")

</div>

> [@dpo](#):
>
> One solution appears to be to enclose the library and symbols definitions in the module’s ` __init__ ` . At least, that worked for AMD.jl.

Yes, pointers will not survive the serialization + deserialization roundtrip from precompilation. Either re-initialize them in ` __init__ ` or turn off precompilation.

---

<div class="post-metadata">

### Author: ![yutaka](https://avatars.discourse-cdn.com/v4/letter/y/dc4da7/32.png) [@yutaka](https://discourse.julialang.org/u/yutaka)
#### Post date: [August 17, 2018, 3:03pm UTC](https://discourse.julialang.org/t/null-function-pointer-in-a-function-creaded-with-eval/13202/7 "2018-08-17T15:03:17Z")

</div>

Thank you for the solution and the explanation! I confirmed that AMD.jl in the master branch passed the tests in Julia 0.7.

---

<div class="post-metadata">

### Author: ![dpo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpo/32/3335_2.png) [@dpo](https://discourse.julialang.org/u/dpo)
#### Post date: [August 17, 2018, 11:22pm UTC](https://discourse.julialang.org/t/null-function-pointer-in-a-function-creaded-with-eval/13202/8 "2018-08-17T23:22:53Z")

</div>

We have @abelsiqueira to thank for the solution!
