1. Returning structs in c_func

Forked from Re: Need help with creating a GUI window on Linux using libxcb.so XCB API

jimcbrown said...

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

new topic     » topic index » view message » categorize

2. Re: Returning structs in c_func

mattlewis said...
jimcbrown said...
mattlewis said...
ghaberek said...

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?

mattlewis said...

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.

mattlewis said...

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

mattlewis said...

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.

new topic     » goto parent     » topic index » view message » categorize

3. Re: Returning structs in c_func

jimcbrown said...
mattlewis said...

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"

mattlewis said...

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

new topic     » goto parent     » topic index » view message » categorize

4. Re: Returning structs in c_func

jimcbrown said...
mattlewis said...

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.

jimcbrown said...
mattlewis said...

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.

jimcbrown said...
mattlewis said...

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

new topic     » goto parent     » topic index » view message » categorize

5. Re: Returning structs in c_func

mattlewis said...
jimcbrown said...
mattlewis said...

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.

new topic     » goto parent     » topic index » view message » categorize

6. Re: Returning structs in c_func

jimcbrown said...

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*
new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu