[MacRuby-devel] Structs are broken

2012-03-13 Thread Fjölnir Ásgeirsson
I've been struggling with accessing C structs from ruby. The problem is:

I expose a struct from my framework (definition below). However when 
accessing/allocating it from ruby it seems the offsets are off by 4 bytes (as 
if macruby think it's supposed to be a double)

Definition:

#ifndef __SCRIPTINGBRIDGE__
union _vec3_t {
float f[3];
struct { float x; float y; float z; };
struct { float r; float g; float b; };
struct { vec2_t xy; float andY; };
};
typedef union _vec3_t vec3_t;
#else
typedef struct _vec3_t { float x; float y; float z; } vec3_t; // Bridgesupport 
freaks out when given the above union so I show it a struct with the same layout
#endif

Example output:

irb(main):001:0> framework "./GLMath.framework"
=> true
irb(main):002:0> v1 = vec3_create(1,2,3)
=> #
irb(main):003:0> v2 = v1.class.new(4,5,6)
=> #
irb(main):004:0> printVec3(v1)
0x676f1310 - 0x676f1314 - 0x676f1318
Vec3: [1.00, 0.00, 3.00]
=> nil
irb(main):005:0> printVec3(v2)
0x676f1310 - 0x676f1314 - 0x676f1318
Vec3: [4.00, 0.00, 5.00]
=> nil

in the above example, vec3_create & printVec3 are C functions, shared using the 
scripting bridge. So when the struct is allocated from the c side, ruby only 
sees the first & last items, and the last item is on the offset of the second. 
when I then pass it to printVec3, it gets the first and last items only (last 
item taken from the place of the second item, => offsets are double what they 
should be). then when I allocate it using FFI in ruby, it's correcly read from 
the ruby side, but when I pass it to a c function, it gets the first item in 
the correct place, then the second item in the place of the last.

The type definitions in my bridge support file are:












Right now I'm working around this by wrapping everything in an object on the 
objective-c side, but that is very slow and bloated.

Has anyone ever gotten structs to work properly or know what is causing this?

Note: if I return a pointer to the struct, and then assign to it's address 
using a boxed struct created from ruby, that works fine it seems. It's only if 
I return a struct directly.
(However, myPointer[0].x = foo; would not work. I'd have to do 
a=myPointer[0];a.x=foo;myPointer[0]=a)

– Fjölnir



smime.p7s
Description: S/MIME cryptographic signature
___
MacRuby-devel mailing list
[email protected]
http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel


Re: [MacRuby-devel] Structs are broken

2012-03-13 Thread Fjölnir Ásgeirsson
One thing I forgot to mention: If I switch the struct to use doubles, then 
everything works fine (which is probably why this didn't get caught sooner, 
since the appkit types all use doubles)

On 2012/03/13, at 22:06, Fjölnir Ásgeirsson wrote:

> I've been struggling with accessing C structs from ruby. The problem is:
> 
> I expose a struct from my framework (definition below). However when 
> accessing/allocating it from ruby it seems the offsets are off by 4 bytes (as 
> if macruby think it's supposed to be a double)
> 
> Definition:
> 
> #ifndef __SCRIPTINGBRIDGE__
> union _vec3_t {
>   float f[3];
>   struct { float x; float y; float z; };
>   struct { float r; float g; float b; };
>   struct { vec2_t xy; float andY; };
> };
> typedef union _vec3_t vec3_t;
> #else
> typedef struct _vec3_t { float x; float y; float z; } vec3_t; // 
> Bridgesupport freaks out when given the above union so I show it a struct 
> with the same layout
> #endif
> 
> Example output:
> 
> irb(main):001:0> framework "./GLMath.framework"
> => true
> irb(main):002:0> v1 = vec3_create(1,2,3)
> => #
> irb(main):003:0> v2 = v1.class.new(4,5,6)
> => #
> irb(main):004:0> printVec3(v1)
> 0x676f1310 - 0x676f1314 - 0x676f1318
> Vec3: [1.00, 0.00, 3.00]
> => nil
> irb(main):005:0> printVec3(v2)
> 0x676f1310 - 0x676f1314 - 0x676f1318
> Vec3: [4.00, 0.00, 5.00]
> => nil
> 
> in the above example, vec3_create & printVec3 are C functions, shared using 
> the scripting bridge. So when the struct is allocated from the c side, ruby 
> only sees the first & last items, and the last item is on the offset of the 
> second. when I then pass it to printVec3, it gets the first and last items 
> only (last item taken from the place of the second item, => offsets are 
> double what they should be). then when I allocate it using FFI in ruby, it's 
> correcly read from the ruby side, but when I pass it to a c function, it gets 
> the first item in the correct place, then the second item in the place of the 
> last.
> 
> The type definitions in my bridge support file are:
> 
>  type='{_vec3_t="x"f"y"f"z"f}'/>
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> Right now I'm working around this by wrapping everything in an object on the 
> objective-c side, but that is very slow and bloated.
> 
> Has anyone ever gotten structs to work properly or know what is causing this?
> 
> Note: if I return a pointer to the struct, and then assign to it's address 
> using a boxed struct created from ruby, that works fine it seems. It's only 
> if I return a struct directly.
> (However, myPointer[0].x = foo; would not work. I'd have to do 
> a=myPointer[0];a.x=foo;myPointer[0]=a)
> 
> – Fjölnir
> 
> ___
> MacRuby-devel mailing list
> [email protected]
> http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel



smime.p7s
Description: S/MIME cryptographic signature
___
MacRuby-devel mailing list
[email protected]
http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel