Use Ptr{StructB} to exactly match the c declaration
StrPack isn't necessary for a simple struct like this, a regular type has
the same layout as a struct
Declaring it immutable defines how Julia can modify it, it does not put
restrictions on what C does with it
On Friday, May 9, 2014, Karanveer Mohan <[email protected]> wrote:
> Hi,
>
> I'm a new Julia user, so bear with me. I believe I can convert a type into
> a structure input for ccall using StrPack. What I'm stuck on is when a
> struct points to another struct like in this case:
>
>
> struct structB
> {
> int val;
> };
>
> struct structA
> {
> int val;
> struct structB * struct_b;
> };
>
> int test(struct structA *struct_a)
> {
> fprintf(stderr, "%d\n", struct_a->val);
> fprintf(stderr, "Got val from struct_a\n");
> fprintf(stderr, "%d\n", (struct_a->struct_b)->val);
> return 1;
> }
>
>
>
> When I try to access val of structA, everything works fine, but it faults
> when trying to access val of structB through structA
> (struct_a->struct_b->val).
>
> My Julia code looks like this:
> using StrPack
> @struct type StructB
> val::Int32
>
> function StructB(val)
> new(convert(Int32, val))
> end
> end
>
> @struct type StructA
> val_one::Int32
> struct_b::StructB
>
> function StructA(val_one, struct_b::StructB)
> new(convert(Int32, val_one), struct_b)
> end
> end
>
> function test()
> struct_b = StructB(1)
> struct_a = StructA(1, struct_b)
>
> struct_a_str = IOBuffer()
> pack(struct_a_str, struct_a)
>
> return_val = ccall((:test, "test.so"), Int32, (Ptr{Void}, ),
> struct_a_str.data)
> end
>
> When this didn't work, I tried to be a bit more 'clever' and use
> pointer_from_objref to point to structB like this:
> using StrPack
> @struct type StructB
> val::Int32
>
> function StructB(val)
> new(convert(Int32, val))
> end
> end
>
> @struct type StructA
> val_one::Int32
> ptr::Ptr{None}
>
> function StructA(val_one, ptr::Ptr{None})
> new(convert(Int32, val_one), ptr)
> end
> end
>
> struct_b = StructB(10)
> struct_b_str = IOBuffer()
> pack(struct_b_str, struct_b)
> struct_a = StructA(1, pointer_from_objref(struct_b_str.data))
> struct_a_str = IOBuffer()
> pack(struct_a_str, struct_a)
>
> return_val = ccall((:test, "test.so"), Int32, (Ptr{Void}, ),
> struct_a_str.data)
>
>
>
> While this doesn't crash, it seems to be returning garbage values for
> struct_b->val. I also can't make these types immutable since I expect the C
> library I'm using to update them.
>
> Any help would be appreciated. Apologies if this is a stupid question.
>