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):
#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:
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:
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!