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.
>

Reply via email to