1. Returning structs in c_func
- Posted by ghaberek (admin) Jul 03, 2013
- 2261 views
Forked from Re: Need help with creating a GUI window on Linux using libxcb.so XCB API
Here's a C wrapper, if you want/need to use that version of the code instead:
/* C wrapper for dealing with C functions that return structs */ #include <xcb/xcb.h> xcb_screen_iterator_t * eu_xcb_setup_roots_iterator(const xcb_setup_t * setup) { xcb_screen_iterator_t iter = xcb_setup_roots_iterator(setup); return &iter; }
Side note: I know Matt's been working on struct support for 4.1. Any chance that could make its way to returning structs-by-value via c_func? This would help with a few other libraries as well.
-Greg
2. Re: Returning structs in c_func
- Posted by jimcbrown (admin) Jul 03, 2013
- 2274 views
Side note: I know Matt's been working on struct support for 4.1. Any chance that could make its way to returning structs-by-value via c_func/c_proc? This would help with a few other libraries as well.
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.
We'd have to figure out how to get that stuff off the stack. Yuck.
Hmm. Is this really more difficult than doing some pop() calls, like older versions of be_callc.c used to do for integer return types?
And I suspect it will work differently on different architectures. Double yuck.
I would have thought that this would actually depend on calling convention... I see no reason for the assembly code to work differently on an ARM vs x86-64 for this case.
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 have thought of a way to get this to work, but it may be too ugly to implement. (It resembles the trick used to implement callbacks in the DOS branch, working around the issue of copying memory around that presumbly caused the DOS extender to bomb out.)
I would rather return a sequence containing the data as it would appear if you peeked it as a memstruct.
Matt
I agree that this is the better approach, but we'd need to support memstructs first before this can be done.
3. 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
4. Re: Returning structs in c_func
- Posted by mattlewis (admin) Jul 03, 2013
- 2189 views
We'd have to figure out how to get that stuff off the stack. Yuck.
Hmm. Is this really more difficult than doing some pop() calls, like older versions of be_callc.c used to do for integer return types?
Could be. I just have no clue, personally.
And I suspect it will work differently on different architectures. Double yuck.
I would have thought that this would actually depend on calling convention... I see no reason for the assembly code to work differently on an ARM vs x86-64 for this case.
Possibly. But they're all finicky in different ways.
I would rather return a sequence containing the data as it would appear if you peeked it as a memstruct.
I agree that this is the better approach, but we'd need to support memstructs first before this can be done.
Yes. But it makes my head hurt to think that we're going to do it wrong.
Matt
5. Re: Returning structs in c_func
- Posted by jimcbrown (admin) Jul 03, 2013
- 2211 views
I would rather return a sequence containing the data as it would appear if you peeked it as a memstruct.
I agree that this is the better approach, but we'd need to support memstructs first before this can be done.
Yes. But it makes my head hurt to think that we're going to do it wrong.
Matt
I think that if we have no other choice, then we do it this way first and fix it up later.
Of course, 4.1.0 is already under a feature freeze, so there's no real harm in implementing this in the memstructs branch itself, and merging it all in when it's ready.
6. Re: Returning structs in c_func
- Posted by jimcbrown (admin) May 18, 2014
- 1945 views
Of course, 4.1.0 is already under a feature freeze, so there's no real harm in implementing this in the memstructs branch itself, and merging it all in when it's ready.
- Bump*