# Creating C structs with pointers to other structs

**URL:** <https://discourse.julialang.org/t/creating-c-structs-with-pointers-to-other-structs/29121>\
**Category:** General Usage\
**Created:** [September 24, 2019, 4:46pm UTC](https://discourse.julialang.org/t/creating-c-structs-with-pointers-to-other-structs/29121 "2019-09-24T16:46:56Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![cshenton](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cshenton/32/9326_2.png) [@cshenton](https://discourse.julialang.org/u/cshenton)\
**Post date:** [September 24, 2019, 4:46pm UTC](https://discourse.julialang.org/t/creating-c-structs-with-pointers-to-other-structs/29121/1 "2019-09-24T16:46:56Z")

</div>

Suppose we have the following structs matching some structs in a C header:

```julia
struct Foo
    a::UInt32
    b::Cstring
end

struct Bar
    a::UInt32
    b::Ptr{Foo}
end

```

And we have a function that takes a ptr to Bar. `ccall` will handle one conversion (from Bar to a Bar pointer) for us, and writing a function that takes a `Bar` and calls `ccall` will ensure a julia ref exists for the scope of the C function call.

However that’s not true for Bar’s field `b`. What’s the idiomatic way to create a pointer to a `Foo`, since `pointer_from_objref` should not be called on immutables?

As a follow on, what’s the “julian” way to redefine these types so that they use julia strings and refs and conversion “just works”?

---

<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:** [September 25, 2019, 1:57am UTC](https://discourse.julialang.org/t/creating-c-structs-with-pointers-to-other-structs/29121/2 "2019-09-25T01:57:47Z")

</div>

> [@cshenton](#):
>
> `ccall` will handle one conversion (from Bar to a Bar pointer) for us, and writing a function that takes a `Bar` and calls `ccall` will ensure a julia ref exists for the scope of the C function call.

I’m confused. Does `ccall` really do that conversion if you doesn’t overload Base.cconvert? What does your ccall signature look like? To pass `Bar` to a C function that accepts `Ptr{Bar}`, the common way is to wrap `Bar` into a `Ref` (`Ref{Bar}`) and then pass it to `ccall` and the conversion from `Ref{Bar}` to `Ptr{Bar}` just works. As for `Foo`, it’s similar.

---

<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 25, 2019, 2:47am UTC](https://discourse.julialang.org/t/creating-c-structs-with-pointers-to-other-structs/29121/3 "2019-09-25T02:47:20Z")

</div>

> [@cshenton](#):
>
> What’s the idiomatic way to create a pointer to a `Foo` , since `pointer_from_objref` should not be called on immutables?

```julia
fooref = Ref(foo_object)
GC.@preserve fooref begin
    ptr = Base.unsafe_convert(Ptr{Foo}, fooref)
    ....some code using ptr....
end

```

Here, I used `GC.@preserve` to make sure that the `fooref` object lives for as long as I need `ptr`. Other strategies can also be employed (e.g. stashing `fooref` in some persistent data structure) if you need `ptr` to be valid for a longer time.

---

<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:** [September 25, 2019, 2:52am UTC](https://discourse.julialang.org/t/creating-c-structs-with-pointers-to-other-structs/29121/4 "2019-09-25T02:52:09Z")

</div>

is `GC.@protect` the new syntax for `GC.@preserve` in the upcoming release?

---

<div class="post-metadata">

**Author:** ![cshenton](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cshenton/32/9326_2.png) [@cshenton](https://discourse.julialang.org/u/cshenton)\
**Post date:** [September 25, 2019, 12:11pm UTC](https://discourse.julialang.org/t/creating-c-structs-with-pointers-to-other-structs/29121/5 "2019-09-25T12:11:44Z")

</div>

> [@Gnimuc](#):
>
> Does `ccall` really do that conversion if you doesn’t overload Base.cconvert?

You are correct, this was a total misconception on my behalf here.

> [@stevengj](#):
>
> Here, I used `GC.@protect` to make sure that the `fooref` object lives for as long as I need `ptr` . Other strategies can also be employed (e.g. stashing `fooref` in some persistent data structure) if you need `ptr` to be valid for a longer time.

Right, so first we need to create a julia reference, then use `unsafe_convert` for the pointer conversion, and make sure that reference sticks around so the GC doesn’t clean up the memory while we’re using it.

What is `pointer_from_objref` even for?

---

<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 25, 2019, 12:13pm UTC](https://discourse.julialang.org/t/creating-c-structs-with-pointers-to-other-structs/29121/6 "2019-09-25T12:13:07Z")

</div>

> [@Gnimuc](#):
>
> is `GC.@protect` the new syntax for `GC.@preserve` in the upcoming release?

Sorry, that was a mistake — corrected now.

---

<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 25, 2019, 12:18pm UTC](https://discourse.julialang.org/t/creating-c-structs-with-pointers-to-other-structs/29121/7 "2019-09-25T12:18:21Z")

</div>

> [@cshenton](#):
>
> What is `pointer_from_objref` even for?

For **rare** applications that need to store “raw” pointers to the underlying native Julia object. For example, it is [used in PyCall](https://github.com/JuliaPy/PyCall.jl/blob/5f141ee51324d5cfdedaf1f8310d20f2fcebf281/src/pytype.jl#L428-L448) to stuff a reference to a native Julia object into a Python “wrapper” object that can be used to refer to the Julia object from Python.

---

<div class="post-metadata">

**Author:** ![cshenton](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cshenton/32/9326_2.png) [@cshenton](https://discourse.julialang.org/u/cshenton)\
**Post date:** [September 25, 2019, 12:24pm UTC](https://discourse.julialang.org/t/creating-c-structs-with-pointers-to-other-structs/29121/8 "2019-09-25T12:24:43Z")

</div>

Would an example use of this be a C api that supports callbacks with user data (for example using a `glfwGetWindowUserPointer` in a window resize callback)? i.e. cases where we want a callback to be run on a native julia object?

(with the understanding that we’d probably have fewer headaches if we just captured that reference within the callback itself for most use cases)

---

<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 25, 2019, 12:44pm UTC](https://discourse.julialang.org/t/creating-c-structs-with-pointers-to-other-structs/29121/9 "2019-09-25T12:44:39Z")

</div>

> [@cshenton](#):
>
> Would an example use of this be a C api that supports callbacks with user data (for example using a `glfwGetWindowUserPointer` in a window resize callback)? i.e. cases where we want a callback to be run on a native julia object?

No. These days, the pointer conversion in such cases can be done via `Any` arguments.

For example, suppose I have a C function that calls a user function with some pass-through data:

```julia
int dosomething(int (*callback)(int, void*), void *data)
{
     int i, s = 0;
     for (i = 0; i < 5; ++i)
          s += callback(i, data);
     return s;
}

```

and I want to be able to call it with a Julia function. I would write something like:

```julia
callback_wrapper(i, callback)::Cint = callback(i)
function dosomething(callback)
    c_callback_wrapper = @cfunction(callback_wrapper, Cint, (Cint, Any,))
    ccall((:dosomething,"libfoo"), Cint, (Ptr{Cvoid}, Any), c_callback_wrapper, callback)
end

```

and if you wanted to pass through an additional Julia object to your function you would then just use a closure, e.g.

```julia
julia> x = 3
3

julia> dosomething(i -> i * x) # pass additional object x via closure
30

julia> dosomething(i -> begin; println("callback($i)"); i * x; end)
callback(0)
callback(1)
callback(2)
callback(3)
callback(4)
30

```

---

<div class="post-metadata">

**Author:** ![cshenton](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cshenton/32/9326_2.png) [@cshenton](https://discourse.julialang.org/u/cshenton)\
**Post date:** [September 25, 2019, 12:48pm UTC](https://discourse.julialang.org/t/creating-c-structs-with-pointers-to-other-structs/29121/10 "2019-09-25T12:48:38Z")

</div>

This approach makes a lot more sense, since it’s not too far how one would handle such a callback object from C++.

Thanks so much for the help Steven!
