# How to load the values returned by callback functions (defined in a Julia wrapper) to C functions

**URL:** <https://discourse.julialang.org/t/how-to-load-the-values-returned-by-callback-functions-defined-in-a-julia-wrapper-to-c-functions/53403>\
**Category:** New to Julia\
**Tags:** package, binarybuilder\
**Created:** [January 15, 2021, 7:50pm UTC](https://discourse.julialang.org/t/how-to-load-the-values-returned-by-callback-functions-defined-in-a-julia-wrapper-to-c-functions/53403 "2021-01-15T19:50:05Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![ven-k](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ven-k/32/11915_2.png) [@ven-k](https://discourse.julialang.org/u/ven-k)\
**Post date:** [January 15, 2021, 7:50pm UTC](https://discourse.julialang.org/t/how-to-load-the-values-returned-by-callback-functions-defined-in-a-julia-wrapper-to-c-functions/53403/1 "2021-01-15T19:50:06Z")

</div>

[4/6 and 5/6 solved it] I am trying to wrap [ngspice\_jll.jl](https://github.com/JuliaBinaryWrappers/ngspice_jll.jl) And have generated wrapper functions to [sharedspice.h](https://github.com/imr/ngspice/blob/master/src/include/ngspice/sharedspice.h) file.

A typical function has pointers to callback functions as arguments. Initialization looks like:

```julia
function ngSpice_Init(sendchar, statfcn) #and 5 more similar callbacks
    ccall((:ngSpice_Init, libngspice), Cint, (Ptr{Cvoid}, Ptr{Cvoid}), sendchar, statfcn)
end

```

where `sendchar = @cfunction($SendChar, Cint, (Ptr{Char}, Cint, Ptr{Cvoid})).ptr`

(And `SendChar` is supposed to print the string pointed by Ptr{Char})

After executing `ngSpice_Init(...)`, and loading circuit, I want to access the sendchar and its arguement. (This and other callbacks are expected to contain info about the simulation being run) When I `unsafe_load` it, as expected, points to nothing. `unsafe_pointer_to_objref` crashes the repl. What should I do to access the string (and other values) returned by the callback function.

---

<div class="post-metadata">

**Author:** ![Keno](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/keno/32/285_2.png) [@Keno](https://discourse.julialang.org/u/Keno)\
**Post date:** [January 15, 2021, 7:52pm UTC](https://discourse.julialang.org/t/how-to-load-the-values-returned-by-callback-functions-defined-in-a-julia-wrapper-to-c-functions/53403/2 "2021-01-15T19:52:26Z")

</div>

`sendchar` looks like a callback. Why are you trying to unsafe\_load it?

---

<div class="post-metadata">

**Author:** ![ven-k](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ven-k/32/11915_2.png) [@ven-k](https://discourse.julialang.org/u/ven-k)\
**Post date:** [January 15, 2021, 8:10pm UTC](https://discourse.julialang.org/t/how-to-load-the-values-returned-by-callback-functions-defined-in-a-julia-wrapper-to-c-functions/53403/3 "2021-01-15T20:10:43Z")

</div>

The ngSpice functions return 0 on execution. Most of the time it prints the status to its own console. And callbacks are supposed to have this info.

---

<div class="post-metadata">

**Author:** ![Keno](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/keno/32/285_2.png) [@Keno](https://discourse.julialang.org/u/Keno)\
**Post date:** [January 15, 2021, 8:32pm UTC](https://discourse.julialang.org/t/how-to-load-the-values-returned-by-callback-functions-defined-in-a-julia-wrapper-to-c-functions/53403/4 "2021-01-15T20:32:27Z")

</div>

Alright, so `@cfunction` creates a C pointer that is a callback to a julia function (in this case SendChar). So whenever ngspice invokes the `sendchar` function pointer you passed, it will end up coming through on the Julia side by invoking the `SendChar` function. Doing an `unsafe_pointer_to_objref` on `sendchar` doesn’t make sense, because it’s not a julia object. It’s a c function pointer. What you’ll want to do is implement the `SendChar` method and inside there handle whatever arguments ngspice gives to the callback.

---

<div class="post-metadata">

**Author:** ![Gnimuc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gnimuc/32/2194_2.png) [@Gnimuc](https://discourse.julialang.org/u/Gnimuc)\
**Post date:** [January 16, 2021, 2:06am UTC](https://discourse.julialang.org/t/how-to-load-the-values-returned-by-callback-functions-defined-in-a-julia-wrapper-to-c-functions/53403/5 "2021-01-16T02:06:49Z")

</div>

> **[Passing Julia Callback Functions to C](https://julialang.org/blog/2013/05/callback/)**
>
> Passing Julia Callback Functions to C | One of the great strengths of Julia is that it is so easy to call C...

This post is probably obsoleted but it’s still a good reading material on how to pass Julia callback functions to C.

I didn’t test the following code, but I guess you could get the idea.

```julia
function sendchar(str::Ptr{Cchar}, id::Cint, userData)::Cint
    push!(userData, unsafe_string(str))
    # I'm not sure what should be returned by this callback function, the header file doesn't tell much
    # maybe the id, maybe just 0 as you mentioned above, you may need to dive into the code of `ngSpice_Init`.
    return 0 or id? 
end

user_data = String[] # you may need a more complex Julia structure for user_data, here I just make it as a string vector.
sendchar_fptr = @cfunction(sendchar, Cint, (Ptr{Cchar}, Cint, Ref{Vector{String}}))

function ngSpice_Init(sendchar, userData) #and 5 more similar callbacks
    ccall((:ngSpice_Init, libngspice), Cint, (Ptr{Cvoid}, Any), sendchar, userData)
end

ngSpice_Init(sendchar_fptr, user_data)

```

---

<div class="post-metadata">

**Author:** ![ven-k](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ven-k/32/11915_2.png) [@ven-k](https://discourse.julialang.org/u/ven-k)\
**Post date:** [January 16, 2021, 4:22am UTC](https://discourse.julialang.org/t/how-to-load-the-values-returned-by-callback-functions-defined-in-a-julia-wrapper-to-c-functions/53403/6 "2021-01-16T04:22:13Z")

</div>

Thank you @Keno and @Gnimuc.

Although I had defined `function sendchar(...)`, I had totally mistaken that it would work only after I explicitly do “something” with the `sendchar_ptr` before invoking it. Now the workflow is clear. Thanks again!
