# Calling C API with pointer inside of a struct

**URL:** <https://discourse.julialang.org/t/calling-c-api-with-pointer-inside-of-a-struct/76029>\
**Category:** New to Julia\
**Tags:** question, ccall\
**Created:** [February 8, 2022, 3:02pm UTC](https://discourse.julialang.org/t/calling-c-api-with-pointer-inside-of-a-struct/76029 "2022-02-08T15:02:24Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![kryptan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kryptan/32/33603_2.png) [@kryptan](https://discourse.julialang.org/u/kryptan)\
**Post date:** [February 8, 2022, 3:02pm UTC](https://discourse.julialang.org/t/calling-c-api-with-pointer-inside-of-a-struct/76029/1 "2022-02-08T15:02:24Z")

</div>

Consider the following C API:

```nohighlight
struct Options {
    uint32_t a;
    uint32_t b;
    void* extra;
};

struct OptionsExtra {
    uint32_t c;
    uint32_t d;
};

void foo(struct Options const* options);

```

It can be used from C as follows:

```nohighlight
foo(&(struct Options) {
    .a = 1,
    .b = 2,
    .extra = &(struct OptionsExtra) {
        .c = 3,
        .d = 4,
    }
});

```

I redeclared this API in Julia:

```nohighlight
struct Options
    a::UInt32
    b::UInt32
    extra::Ptr{Cvoid}
end

struct OptionsExtra
    c::UInt32
    d::UInt32
end

function foo(options)::Cvoid
    ccall((:foo, lib), Cvoid, (Ref{Options},), options)
end

```

How should I construct `extra` pointer in a call to `foo`?

```nohighlight
extra = OptionsExtra(3, 4)
foo(Options(1, 2, #= what goes here? =#))

```

`pointer` function only works with arrays and `pointer_from_objref` only with mutable objects.

As a workaround I can put `extra` in an array:

```nohighlight
extra = [OptionsExtra(3, 4)]
GC.@preserve extra foo(Options(1, 2, pointer(extra)))

```

But this seems overcomplicated and suboptimal as it involves heap allocation while C version allocates everything on the stack.

Is there any better way to do this?

---

<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:** [February 9, 2022, 12:57am UTC](https://discourse.julialang.org/t/calling-c-api-with-pointer-inside-of-a-struct/76029/2 "2022-02-09T00:57:22Z")

</div>

You can make `OptionsExtra` mutable, so you can directly use `pointer_from_objref` on it without wrapping it in another container. But I’m not sure this solution will satisfy you.

---

<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:** [February 9, 2022, 3:44am UTC](https://discourse.julialang.org/t/calling-c-api-with-pointer-inside-of-a-struct/76029/3 "2022-02-09T03:44:58Z")

</div>

> [@kryptan](#):
>
> As a workaround I can put `extra` in an array:
> 
> ```julia
> extra = [OptionsExtra(3, 4)]
> GC.@preserve extra foo(Options(1, 2, pointer(extra)))
> 
> ```

You could also use `Ref(OptionsExtra(3,4))` + `Base.usafe_convert`.

---

<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:** [February 9, 2022, 3:48am UTC](https://discourse.julialang.org/t/calling-c-api-with-pointer-inside-of-a-struct/76029/4 "2022-02-09T03:48:05Z")

</div>

> [@kryptan](#):
>
> But this seems overcomplicated and suboptimal as it involves heap allocation while C version allocates everything on the stack.

There is no way to avoid heap allocations if your C API expects a pointer, you could change the C API to pass-by-value though.
