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) > => #<vec3_t x=1.0 y=3.0 z=NaN> > irb(main):003:0> v2 = v1.class.new(4,5,6) > => #<vec3_t x=4.0 y=5.0 z=6.0> > 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: > > <struct name='vec3_t' > type='{_vec3_t="x"f"y"f"z"f}'/> > <function name='vec3_create' inline='true'> > <arg type='f'/> > <arg type='f'/> > <arg type='f'/> > <retval type='{_vec3_t=fff}'/> > </function> > <function name='printVec3'> > <arg type='{_vec3_t=fff}'/> > </function> > > 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 > MacRuby-devel@lists.macosforge.org > http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
smime.p7s
Description: S/MIME cryptographic signature
_______________________________________________ MacRuby-devel mailing list MacRuby-devel@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel