# Passing a context pointer from Julia through C seems to fail: what am I doing wrong?

**URL:** <https://discourse.julialang.org/t/passing-a-context-pointer-from-julia-through-c-seems-to-fail-what-am-i-doing-wrong/17842>\
**Category:** New to Julia\
**Created:** [November 22, 2018, 6:10am UTC](https://discourse.julialang.org/t/passing-a-context-pointer-from-julia-through-c-seems-to-fail-what-am-i-doing-wrong/17842 "2018-11-22T06:10:50Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![frtps](https://avatars.discourse-cdn.com/v4/letter/f/73ab20/32.png) [@frtps](https://discourse.julialang.org/u/frtps)\
**Post date:** [November 22, 2018, 6:10am UTC](https://discourse.julialang.org/t/passing-a-context-pointer-from-julia-through-c-seems-to-fail-what-am-i-doing-wrong/17842/1 "2018-11-22T06:10:50Z")

</div>

I am trying to interface with some legacy C code that takes both a callback function pointer and an opaque pointer to context to use as an argument when calling back. The function pointer generated by Julia is understood by C and calls back to Julia but the contents of the context seem to be lost. Here is a minimal working example:

```julia
# A minimal working example to show how we can get a Julia struct to
# round-trip through C

mutable struct context
    test1::Int32
    test2::Float64
    test3::String
end

mutable struct handler_list
    the_fun::Ptr{Nothing}
end

my_handler(a::context)::Cint = begin
    println("$(a.test1)")
    println("$(a.test2)")
    println("$(a.test3)")
    return 0
end

test() = begin
    a = @cfunction(my_handler,Cint,(context,))
    hl = handler_list(a)
    my_context = context(1,2.0,"33333")
    ccall((:set_and_run,"./libmwe"),Cint,(Ref{handler_list},Ref{context}),Ref(hl),Ref(my_context))
end

test()

```

and the C code is simply:

```julia
/* A small library function to demonstrate passing a struct to and from Julia */
typedef struct handler_s {
  int (*handle_data)(void *context);
} handler_tp;

void set_and_run(handler_tp *f, void *context) {
  f->handle_data(context);
}

```

The C code is compiled with `gcc -g -shared -o libmwe.so mwe_struct.c`

When I run this with `julia mwe_struct.jl` I get a segfault. I have verified with gdb in the `set_and_run` function that the context is a pointer that points to the beginning of `my_context`.

So what am I doing wrong?

---

<div class="post-metadata">

**Author:** ![y4lu](https://avatars.discourse-cdn.com/v4/letter/y/47e85d/32.png) [@y4lu](https://discourse.julialang.org/u/y4lu)\
**Post date:** [November 22, 2018, 6:55am UTC](https://discourse.julialang.org/t/passing-a-context-pointer-from-julia-through-c-seems-to-fail-what-am-i-doing-wrong/17842/2 "2018-11-22T06:55:44Z")

</div>

It might be trying to return void (from set\_and\_run) as a `Cint`

---

<div class="post-metadata">

**Author:** ![frtps](https://avatars.discourse-cdn.com/v4/letter/f/73ab20/32.png) [@frtps](https://discourse.julialang.org/u/frtps)\
**Post date:** [November 22, 2018, 7:06am UTC](https://discourse.julialang.org/t/passing-a-context-pointer-from-julia-through-c-seems-to-fail-what-am-i-doing-wrong/17842/3 "2018-11-22T07:06:05Z")

</div>

OK, so if I pass in the context as a Ptr{Cvoid} by using `pointer_from_objref` and then unwrap it with `unsafe_pointer_to_objref` in the callback function, everything works. Is that best practice?

---

<div class="post-metadata">

**Author:** ![y4lu](https://avatars.discourse-cdn.com/v4/letter/y/47e85d/32.png) [@y4lu](https://discourse.julialang.org/u/y4lu)\
**Post date:** [November 22, 2018, 7:37am UTC](https://discourse.julialang.org/t/passing-a-context-pointer-from-julia-through-c-seems-to-fail-what-am-i-doing-wrong/17842/4 "2018-11-22T07:37:41Z")

</div>

I’ll have to defer to someone more knowledgeable for best practices here, though i think the `Cint` return type in `ccall` might want to be `Cvoid` just to be safe

---

<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:** [November 22, 2018, 2:09pm UTC](https://discourse.julialang.org/t/passing-a-context-pointer-from-julia-through-c-seems-to-fail-what-am-i-doing-wrong/17842/5 "2018-11-22T14:09:45Z")

</div>

> [@frtps](#):
>
> Ref(hl),Ref(my\_context)

Remove the `Ref`

---

<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:** [November 22, 2018, 2:10pm UTC](https://discourse.julialang.org/t/passing-a-context-pointer-from-julia-through-c-seems-to-fail-what-am-i-doing-wrong/17842/6 "2018-11-22T14:10:28Z")

</div>

> [@frtps](#):
>
> as a Ptr{Cvoid} by using `pointer_from_objref`

Never do this.

> [@frtps](#):
>
> @cfunction(my\_handler,Cint,(context,))

`Ref{context}`

---

<div class="post-metadata">

**Author:** ![frtps](https://avatars.discourse-cdn.com/v4/letter/f/73ab20/32.png) [@frtps](https://discourse.julialang.org/u/frtps)\
**Post date:** [November 22, 2018, 11:10pm UTC](https://discourse.julialang.org/t/passing-a-context-pointer-from-julia-through-c-seems-to-fail-what-am-i-doing-wrong/17842/7 "2018-11-22T23:10:54Z")

</div>

OK, thanks @yuyichao, I can confirm that that works. My fundamental error was to think that if I have `Ref{type}` in the argument type list for `ccall`, then I should also do Ref(object) in the arguments to the ccall. But the correct way to call the function was:

````
```ccall((:set_and_run,"./libmwe"),Cint,(Ref{handler_list},Ref{context}),Ref(hl),my_context)```

````

So this means that `my_context` can have a type of both `context` and `Ref{context}`?

---

<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:** [November 22, 2018, 11:19pm UTC](https://discourse.julialang.org/t/passing-a-context-pointer-from-julia-through-c-seems-to-fail-what-am-i-doing-wrong/17842/8 "2018-11-22T23:19:24Z")

</div>

> [@frtps](#):
>
> Ref(hl)

You don’t need this either.

> [@frtps](#):
>
> So this means that `my_context` can have a type of both `context` and `Ref{context}` ?

Absolutely not. The ccall argument type list defines the ABI and the conversion, it is not a type assertion. It’s the same as passing a `1` to a `Cdouble` ccall argument doesn’t mean the `1` has a type of both `Int` and `Float64`. No object can have more than one concrete type. (`Ref{context}` isn’t a concrete type but it cannot be the same as `context`).
