Re: Returning structs in c_func
- Posted by ghaberek (admin) Jul 03, 2013
- 2278 views
We'd have to understand how compilers handle this. I've never looked to see what they do in those cases, but I agree that it would be extremely useful.
Matt
My understanding was that structs, when returned (passed by value) from a C function, will be passed on the stack. So, a struct made up of 5 elements, each being a 32bit int, will take up 20 bytes of stack space. Likewise, a struct made up of a single element, an array of bytes, with the array having a length of 12, will take up 3 dwords of stack space.
I was thinking that, in these cases, we could somehow encode the length of the struct in the return type, and return a sequence of bytes to be reconstructed by the caller.
My research supports this as well. There are several StackOverflow discussions on this: Google "how does c return struct"
We'd have to figure out how to get that stuff off the stack. Yuck. And I suspect it will work differently on different architectures. Double yuck. Especially considering the semi-hardcoded way we call stuff on x86-64 (and ARM? I can't recall of the top of my head).
I would rather return a sequence containing the data as it would appear if you peeked it as a memstruct.
Matt
I'll leave the stack-smashing attempts to you. :)
But I imagine we would adjust define_c_func() to accept an object for return_type, which could then be the layout of the structure...
typedef struct { int a; unsigned int b; float c; double d; char* x; } myStruct; myStruct myFunc() { myStruct m; m.a = -5; m.b = 100; m.c = 1.0; m.d = 1.23456789; m.x = "Hello world!"; return m; }
constant _myFunc = define_c_func( myLib, "myFunc", {}, {C_INT,C_UINT,C_FLOAT,C_DOUBLE,C_POINTER} ) function myFunc() sequence myStruct = c_func( _myFunc, {} ) -- this is a string pointer myStruct[5] = peek_string( myStruct[5] ) return myStruct end function
-Greg