# Passing a pointer to struct of arrays and bitfields to ccall

**URL:** <https://discourse.julialang.org/t/passing-a-pointer-to-struct-of-arrays-and-bitfields-to-ccall/45254>\
**Category:** General Usage\
**Created:** [August 20, 2020, 8:52am UTC](https://discourse.julialang.org/t/passing-a-pointer-to-struct-of-arrays-and-bitfields-to-ccall/45254 "2020-08-20T08:52:43Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![pauljurczak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pauljurczak/32/921_2.png) [@pauljurczak](https://discourse.julialang.org/u/pauljurczak)\
**Post date:** [August 20, 2020, 8:52am UTC](https://discourse.julialang.org/t/passing-a-pointer-to-struct-of-arrays-and-bitfields-to-ccall/45254/1 "2020-08-20T08:52:43Z")

</div>

I still can’t figure out memory layout of Julia data structures. I have:

```julia
mutable struct Stimuli
  rgb::Array{UInt8, 1}
  depth::Array{Float32, 1}
  batteryLevel::Float32
end

const N = 10^6

stimuli = Stimuli(zeros(UInt8, N), ones(Float32, N), 0.19f0)

```

and I would like to pass a pointer to `stimuli` to C library, so it can write to its fields. The C counterpart is:

```julia
struct Stimuli {
  void *rgb, *depth;
  float batteryLevel;
};

extern "C" void test(Stimuli* stimuli) {...}

```

Both types above can be modified, if it’s necessary for this to work. I tried:

```julia
function test(stimuli)
  @ccall "libsimc.so".test(stimuli::Ptr{Stimuli})::Cvoid
end

```

and

```julia
function test(stimuli)
  @ccall "libsimc.so".test(stimuli::Ref{Stimuli})::Cvoid
end

```

and none of them work. I had it working by passing individual pointers to arrays and wrapping bits-types in a struct, but I don’t know how to put everything into a single struct.

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [August 20, 2020, 9:50am UTC](https://discourse.julialang.org/t/passing-a-pointer-to-struct-of-arrays-and-bitfields-to-ccall/45254/2 "2020-08-20T09:50:26Z")

</div>

Did you read documentation and in particular [Calling C and Fortran Code · The Julia Language](https://docs.julialang.org/en/v1/manual/calling-c-and-fortran-code/#mapping-c-types-to-julia-1)? Also, when interfacing C code I recommend using the system-independent aliases

---

<div class="post-metadata">

**Author:** ![pauljurczak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pauljurczak/32/921_2.png) [@pauljurczak](https://discourse.julialang.org/u/pauljurczak)\
**Post date:** [August 20, 2020, 10:10am UTC](https://discourse.julialang.org/t/passing-a-pointer-to-struct-of-arrays-and-bitfields-to-ccall/45254/3 "2020-08-20T10:10:18Z")

</div>

I’ve read it more than once. Still no cigar.

> [@giordano](#):
>
> interfacing C code I recommend using the system-independent aliases

Do you mean `UInt8` or `Float32` are system dependent?

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [August 20, 2020, 10:21am UTC](https://discourse.julialang.org/t/passing-a-pointer-to-struct-of-arrays-and-bitfields-to-ccall/45254/4 "2020-08-20T10:21:17Z")

</div>

> [@pauljurczak](#):
>
> I’ve read it more than once. Still no cigar.

Well, pointers to void should be `Ptr{Cvoid}`, that’s pretty clearly stated

> [@pauljurczak](#):
>
> Do you mean `UInt8` or `Float32` are system dependent?

No, but _always_ use the aliases and you’ll live happy

---

<div class="post-metadata">

**Author:** ![pauljurczak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pauljurczak/32/921_2.png) [@pauljurczak](https://discourse.julialang.org/u/pauljurczak)\
**Post date:** [August 20, 2020, 10:49am UTC](https://discourse.julialang.org/t/passing-a-pointer-to-struct-of-arrays-and-bitfields-to-ccall/45254/5 "2020-08-20T10:49:55Z")

</div>

> [@giordano](#):
>
> pointers to void should be `Ptr{Cvoid}` , that’s pretty clearly stated

Do you mean change `Stimuli` to:

```julia
mutable struct Stimuli
  rgb::Ptr{Cvoid}
  depth::Ptr{Cvoid}
  batteryLevel::Float32
end

rgb = zeros(UInt8, width*height*3)
depth = ones(Float32, width*height)
stimuli = Stimuli(pointer(rgb), pointer(depth), 0.12f0)

```

This works, thank you!

> [@giordano](#):
>
> _always_ use the aliases

What do you mean by aliases? Type aliases?

---

<div class="post-metadata">

**Author:** ![pauljurczak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pauljurczak/32/921_2.png) [@pauljurczak](https://discourse.julialang.org/u/pauljurczak)\
**Post date:** [August 20, 2020, 10:57am UTC](https://discourse.julialang.org/t/passing-a-pointer-to-struct-of-arrays-and-bitfields-to-ccall/45254/6 "2020-08-20T10:57:37Z")

</div>

Oh, you mean `Cfloat` instead of `Float32`, right?

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [August 20, 2020, 11:32am UTC](https://discourse.julialang.org/t/passing-a-pointer-to-struct-of-arrays-and-bitfields-to-ccall/45254/7 "2020-08-20T11:32:01Z")

</div>

Yes, those type aliases

---

<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:** [August 20, 2020, 12:46pm UTC](https://discourse.julialang.org/t/passing-a-pointer-to-struct-of-arrays-and-bitfields-to-ccall/45254/8 "2020-08-20T12:46:41Z")

</div>

There’s no advantage for using `Cfloat` instead of `Float32`, just keep using whatever you were using is perfectly fine. There’s absolutely nothing system dependent about either and that’s totally unrelated with anything here.

There’s also nothing significant you need to change to the declaration of the type to either the julia type or the C type, as long as you are only passing the data from julia to C and letting julia manage the memory. (If you are letting C allocating something and passing it back to julia that’ll change things a bit.) since the one you have on the julia side is pretty much the most straight forward way to manage the memory and the one you have on the C side is what you’d have for reading and mutating the data. (the pointer type makes no significance in the ABI so you should probably change the C type to have easeir to use pointer types but that has no effect on how you pass things around)

The only thing you need is to create the C struct on the ccall callsite. If you could, it’s of course easier to just pass in the fields individually since you don’t need to repack the pointers into a struct, though this may not be a solution if you have a lot of such calls.

So now the only problem you need to solve is to create a julia structure that matches `struct Stimuli { ... };` in C. After that, you can write unsafe/pseudo code that does the ccall sth like.

```julia
   c_struct = create_c_struct_with_pointers_from_julia_struct_with_array(julia_struct)
   @ccall .... (..., c_struct::Ref{CStruct}, ...)

```

The only reason the code above is invalid is because `julia_struct` will not be kepth valid by the compiler, and you need `GC.@preserve julia_struct begin <code above> end` to make it valid.

From there you can go one step further and figure out how to define `cconvert` and `unsafe_convert` so that you don’t have to use `GC.@preserve` manually.

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [August 20, 2020, 1:20pm UTC](https://discourse.julialang.org/t/passing-a-pointer-to-struct-of-arrays-and-bitfields-to-ccall/45254/9 "2020-08-20T13:20:50Z")

</div>

> [@yuyichao](#):
>
> There’s no advantage for using `Cfloat` instead of `Float32` , just keep using whatever you were using is perfectly fine.

The advantage is to avoid the common `int` → `Int` error, I’ve seen that too many times. And it’s just easier to put `C` in front of the name of the C type.

> [@yuyichao](#):
>
> that’s totally unrelated with anything here.

Did anyone say so?

---

<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:** [August 20, 2020, 1:41pm UTC](https://discourse.julialang.org/t/passing-a-pointer-to-struct-of-arrays-and-bitfields-to-ccall/45254/10 "2020-08-20T13:41:32Z")

</div>

> [@giordano](#):
>
> The advantage is to avoid the common `int` → `Int` error, I’ve seen that too many times. And it’s just easier to put `C` in front of the name of the C type.

And that’s entirely irrelavant for float. Also, if the julia size uses `Int` and if the C side is free to change like in this case, the correct solution is to make sure the C types matches.

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [August 20, 2020, 1:54pm UTC](https://discourse.julialang.org/t/passing-a-pointer-to-struct-of-arrays-and-bitfields-to-ccall/45254/11 "2020-08-20T13:54:53Z")

</div>

> [@yuyichao](#):
>
> And that’s entirely irrelavant for float.

Did anyone say it was relevant for the specific case?

> [@giordano](#):
>
> > [@pauljurczak](#):
> >
> > Do you mean `UInt8` or `Float32` are system dependent?
> 
> No, but _always_ use the aliases and you’ll live happy

---

<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:** [August 20, 2020, 2:10pm UTC](https://discourse.julialang.org/t/passing-a-pointer-to-struct-of-arrays-and-bitfields-to-ccall/45254/12 "2020-08-20T14:10:11Z")

</div>

If you agree it’s irrelavant, then please don’t add noise to an otherwise already non-trivial topic, feel free to start a new one. It’s also an ill advice to “always use the aliases” and as I said especially in this case where making C code match julia code is an option. The advice is not only irrelavant, it’s wrong for this specific thread.
