# C Binding - how to pass pointer to a structure

**URL:** <https://forum.crystal-lang.org/t/c-binding-how-to-pass-pointer-to-a-structure/8044>\
**Category:** Help & Support\
**Created:** [May 8, 2025, 3:24pm UTC](https://forum.crystal-lang.org/t/c-binding-how-to-pass-pointer-to-a-structure/8044 "2025-05-08T15:24:25Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Steve](https://avatars.discourse-cdn.com/v4/letter/s/f19dbf/32.png) [@Steve](https://forum.crystal-lang.org/u/Steve)\
**Post date:** [May 8, 2025, 3:24pm UTC](https://forum.crystal-lang.org/t/c-binding-how-to-pass-pointer-to-a-structure/8044/1 "2025-05-08T15:24:25Z")

</div>

I’m a Crystal newbie and I am trying to create my first C binding but there’s a few aspects I don’t quite understand…

First, how do I pass a pointer to a structure? This is what I’m attempting:

```crystal
# the structure
struct XlsxDateTime
    year : Int32
    month : Int32
    day : Int32
    hour : Int32
    min : Int32
    sec : Float64
end

# the function signature
fun worksheet_write_datetime(worksheet : UInt64, row : UInt32, col : UInt16, datetime : XlsxDateTime*, format : UInt64) : UInt32

# and this is how I'm trying to call it
dt = Xlsx::XlsxDateTime.new
dt.day = 8
dt.month = 5
dt.year = 2025
Xlsx.worksheet_write_datetime(ws, row, col, Pointer(dt), fd)

```

But this gives the error:

```auto
630 | Xlsx.worksheet_write_datetime(ws, row, col, Pointer(dt), fd)
Error: unexpected token: "dt"

```

.  
Also, what is the Crystal syntax when a C function expects a pointer to an array of structures as one of the parameters?

---

<div class="post-metadata">

**Author:** ![Blacksmoke16](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/blacksmoke16/32/1241_2.png) [@Blacksmoke16](https://forum.crystal-lang.org/u/Blacksmoke16)\
**Post date:** [May 8, 2025, 3:56pm UTC](https://forum.crystal-lang.org/t/c-binding-how-to-pass-pointer-to-a-structure/8044/2 "2025-05-08T15:56:25Z")

</div>

`Pointer` represents the type of a pointer, not how you obtain one. I think you’d want to leverage [pointerof - Crystal](https://crystal-lang.org/reference/1.16/syntax_and_semantics/pointerof.html), so something like:

```crystal
Xlsx.worksheet_write_datetime(ws, row, col, pointerof(dt), fd)

```

---

<div class="post-metadata">

**Author:** ![Steve](https://avatars.discourse-cdn.com/v4/letter/s/f19dbf/32.png) [@Steve](https://forum.crystal-lang.org/u/Steve)\
**Post date:** [May 8, 2025, 4:20pm UTC](https://forum.crystal-lang.org/t/c-binding-how-to-pass-pointer-to-a-structure/8044/3 "2025-05-08T16:20:24Z")

</div>

> [@Blacksmoke16](#):
>
> `Xlsx.worksheet_write_datetime(ws, row, col, pointerof(dt), fd)`

Thank you, that’s now working 😁

How do I declare a function that receives a pointer to an array of structures?  
Here’s an example of a C declaration I want to wrap for Crystal:

```c
lxw_error chart_series_set_labels_custom (lxw_chart_series *series, lxw_chart_data_label *data_labels[])

```

Source: [libxlsxwriter: chart.h File Reference](https://libxlsxwriter.github.io/chart_8h.html)

---

<div class="post-metadata">

**Author:** ![kojix2](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/kojix2/32/1583_2.png) [@kojix2](https://forum.crystal-lang.org/u/kojix2)\
**Post date:** [May 8, 2025, 4:42pm UTC](https://forum.crystal-lang.org/t/c-binding-how-to-pass-pointer-to-a-structure/8044/4 "2025-05-08T16:42:59Z")

</div>

The following two are the same

```c
void func(struct Foo *bar[]);

```

```c
void func(struct Foo **bar);

```

And in Crystal, it would look something like this

```cr
fun func(arr : Pointer(Pointer(Foo))) : Void
fun func(arr : Foo**) : Void

```

---

<div class="post-metadata">

**Author:** ![yxhuvud](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/yxhuvud/32/27_2.png) [@yxhuvud](https://forum.crystal-lang.org/u/yxhuvud)\
**Post date:** [May 8, 2025, 9:34pm UTC](https://forum.crystal-lang.org/t/c-binding-how-to-pass-pointer-to-a-structure/8044/5 "2025-05-08T21:34:06Z")

</div>

Another general tip is that lifetimes matter. So if you take a pointer to a local variable, then you must not let the current scope be invalidated. So especially when it comes to defining callbacks that is not an option, and instead you will probably want to define something like

```auto
def to_unsafe
  pointerof(@my_c_struct)
end

```

---

<div class="post-metadata">

**Author:** ![straight-shoota](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/straight-shoota/32/36_2.png) [@straight-shoota](https://forum.crystal-lang.org/u/straight-shoota)\
**Post date:** [May 9, 2025, 8:58am UTC](https://forum.crystal-lang.org/t/c-binding-how-to-pass-pointer-to-a-structure/8044/6 "2025-05-09T08:58:11Z")

</div>

I’d recommend to take a deeper look at the language reference: [About this guide - Crystal](https://crystal-lang.org/reference/1.16/syntax_and_semantics/), especially the sections about C bindings and unsafe code. There are a couple of traps on the way.

For example, the struct definition should either be inside a `lib` or annotated as `@[Extern]` so the compiler preserves the layout as defined.

---

<div class="post-metadata">

**Author:** ![Steve](https://avatars.discourse-cdn.com/v4/letter/s/f19dbf/32.png) [@Steve](https://forum.crystal-lang.org/u/Steve)\
**Post date:** [May 9, 2025, 7:22pm UTC](https://forum.crystal-lang.org/t/c-binding-how-to-pass-pointer-to-a-structure/8044/7 "2025-05-09T19:22:01Z")

</div>

> [@straight-shoota](#):
>
> the struct definition should either be inside a `lib`

It is but I included just enough snippets to frame the question 👍
