# Using ccall to modify fields of Julia struct

**URL:** https://discourse.julialang.org/t/using-ccall-to-modify-fields-of-julia-struct/75835
**Category:** New to Julia
**Tags:** ccall
**Created:** [February 5, 2022, 12:35am UTC](https://discourse.julialang.org/t/using-ccall-to-modify-fields-of-julia-struct/75835 "2022-02-05T00:35:27Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![gpxl](https://avatars.discourse-cdn.com/v4/letter/g/f14d63/32.png) [@gpxl](https://discourse.julialang.org/u/gpxl)
#### Post date: [February 5, 2022, 12:35am UTC](https://discourse.julialang.org/t/using-ccall-to-modify-fields-of-julia-struct/75835/1 "2022-02-05T00:35:27Z")

</div>

I am totally new to Julia in the last week, and I have decided to dive in and try to write a wrapper for a library I frequently use in my research. This library has structs which get initialized by passing them to a function which sets the values appropriately. Here is some simplified C code which reflects this (not from the actual library as that would be too long to include a MWE here):

```julia
#include <string.h>
typedef char Msg[2048];

struct myStruct1{
	double field1;
	double * field2;
};

struct myStruct2{
	double field3;
};

int init_myStruct(struct myStruct1 * s1, struct myStruct2 * s2, Msg m){
	s1->field1 = 5.;
	s1->field2 = &(s1->field1);
	s2->field3 = *(s1->field2);
	const char* tmp = "Initialized";
	strcpy(m, tmp);
	return 1;
}

```

I am trying to wrap this in Julia. The goal here is that I can compute what I need using this library, and once that is done I can do the rest of my analysis in Julia. To do so, I have create analogues of these structs in Julia, and have I think initialized them to be empty and filled later. Here is my Julia code:

```julia
struct JStruct1
	field1::Cdouble
	field2::Ptr{Cdouble}
	JStruct1() = new()
end

struct JStruct2
	field3::Cdouble
	JStruct2() = new()
end

struct MyJuliaStruct
	s1::JStruct1
	s2::JStruct2
	m::NTuple{2048, Cchar}	
	function MyJuliaStruct()
		s1 = JStruct1()
		s2 = JStruct2()
		message=ntuple(x->convert(Cchar, 0*x), 2048)
		new(s1, s2, message)
	end
end

function main()
	s = MyJuliaStruct()
	ccall((:init_myStruct, "libtest.so"), Cint, (Ref{JStruct1}, Ref{JStruct2}, NTuple{2048, Cchar}), Ref(s.s1), Ref(s.s2), s.m)
	println(s.s1.field1)
	println(s.m)
end

main()

```

When I run this however, I get as output:

```julia
0.0
(0, 0, 0, 0, [2048 zeroes here that I won't repeat], 0)

```

The ccall seems to have worked fine but my values are not appropriately modified. I thought that by passing the Julia structs as `Ref(s.s1)`, the memory could be managed by both C and Julia and that this would work. Can anyone point me in the right direction? I have looked at some similar topics but haven’t been able to figure it out. Thanks for reading!

---

<div class="post-metadata">

### Author: ![lucifer1004](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lucifer1004/32/22311_2.png) [@lucifer1004](https://discourse.julialang.org/u/lucifer1004)
#### Post date: [February 5, 2022, 12:48am UTC](https://discourse.julialang.org/t/using-ccall-to-modify-fields-of-julia-struct/75835/2 "2022-02-05T00:48:24Z")

</div>

Have you tried mutable struct?

---

<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 5, 2022, 3:32am UTC](https://discourse.julialang.org/t/using-ccall-to-modify-fields-of-julia-struct/75835/3 "2022-02-05T03:32:02Z")

</div>

> [@gpxl](#):
>
> I thought that by passing the Julia structs as `Ref(s.s1)` , the memory could be managed by both C and Julia and that this would work.

This is not right. It’s basically wrong if you simply translate `&x` to `Ref(x)` in `ccall`. It should be something like:

```julia
x_ref = Ref(x)
ret = ccall(..., x_ref)
x = x_ref[]
ret 

```

> [@gpxl](#):
>
> `ccall((:init_myStruct, "libtest.so"), Cint, (Ref{JStruct1}, Ref{JStruct2}, NTuple{2048, Cchar}), Ref(s.s1), Ref(s.s2), s.m)`

`NTuple{2048, Cchar}` → `Ptr{Cchar}`: In C, array types in the function proto should decay to corresponding pointer types.

`struct MyJuliaStruct` → `mutable struct MyJuliaStruct`: This should be mutable if you’re gonna change the fields. if you’d like to keep it immutable, you could use it in this way:

```julia
s = MyJuliaStruct()
s1_ref = Ref(s.s1)
s2_ref = Ref(s.s2)
m_ref = Ref(s.m)
ccall((:init_myStruct, "libtest.so"), Cint, (Ptr{JStruct1}, Ptr{JStruct2}, Ptr{Cchar}), s1_ref, s2_ref, m_ref)
s = MyJuliaStruct(s1_ref[], s2_ref[], m_ref[])

```

Or you could simply do:

```julia
s1_ref = Ref{JStruct1}()
s2_ref = Ref{JStruct2}()
m_ref = Ref{NTuple{2048, Cchar}}()
ccall((:init_myStruct, "libtest.so"), Cint, (Ptr{JStruct1}, Ptr{JStruct2}, Ptr{Cchar}), s1_ref, s2_ref, m_ref)
s = MyJuliaStruct(s1_ref[], s2_ref[], m_ref[])

```

---

<div class="post-metadata">

### Author: ![gpxl](https://avatars.discourse-cdn.com/v4/letter/g/f14d63/32.png) [@gpxl](https://discourse.julialang.org/u/gpxl)
#### Post date: [February 5, 2022, 11:43pm UTC](https://discourse.julialang.org/t/using-ccall-to-modify-fields-of-julia-struct/75835/5 "2022-02-05T23:43:45Z")

</div>

I somehow deleted my previous post, but that is OK as I want to modify it anyway. Thank you very much for your suggestions, they have been very helpful. I have implemented them as you suggest, so that my main() function is now:

```julia
function main()
	s1_ref = Ref{JStruct1}()
	s2_ref = Ref{JStruct2}()
	m_ref = Ref{NTuple{2048, Cchar}}()
	ccall((:init_myStruct, "libtest.so"), Cint, (Ptr{JStruct1}, Ptr{JStruct2}, Ptr{Cchar}), s1_ref, s2_ref, m_ref)
	s = MyJuliaStruct(s1_ref[], s2_ref[], m_ref[])
	println(s.s1.field1)
	println(s.m)
end

main()

```

Running this gives the following error:

```julia
LoadError: UndefRefError: access to undefined reference
Stacktrace:
 [1] getproperty
   @ ./Base.jl:42 [inlined]
 [2] unsafe_convert
   @ ./refvalue.jl:42 [inlined]
 [3] main()
   @ Main ~/projects/misc/wrapping/cwrap.jl:28
 [4] top-level scope
   @ ~/projects/misc/wrapping/cwrap.jl:34

```

Do you have any idea why this might be happening? It is coming from the ccall itself because I get the same error even when commenting out lines after that.

---

<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 6, 2022, 4:46am UTC](https://discourse.julialang.org/t/using-ccall-to-modify-fields-of-julia-struct/75835/6 "2022-02-06T04:46:50Z")

</div>

> [@gpxl](#):
>
> ```julia
> struct JStruct2
> field3::Cdouble
> JStruct2() = new()
> end
> 
> ```

You don’t need to define `JStruct2() = new()` for isbitstypes, but you could also use `Ref(JStruct1())` instead, if you’d like to keep it.
