On 4 May 2012 18:37, Eliot Miranda <[email protected]> wrote:
>
>
> On Fri, May 4, 2012 at 6:13 AM, Igor Stasenko <[email protected]> wrote:
>>
>> On 4 May 2012 10:38, Luc Fabresse <[email protected]> wrote:
>> > Hi Igor,
>> >
>> >>
>> >> there is a workaround.
>> >> all structs in C is returned via pointer.
>> >> so, actually a true return type of a function is CvSize*
>> >
>> >
>> > I agree that usually structs are returned through pointers.
>> > But here it is not the case.
>> >
>> > I want to wrap this function:
>> > CvSize cvGetSize( const CvArr* arr );
>> >
>> > and the CvSize struct is returned by value. Am I wrong?
>> >
>>
>> i don't know.. this is a bit shady part of C ABI.
>> Some compilers use return-by-value, some return by pointer
>> by forcing a caller to pass a hidden implicit argument as a pointer to
>> the struct, which then filled with values by
>> the function you call.
>
>
> IIRC x86 ABIs (all the ones I encountered at least, windows, mac, linux,
> solaris)  support structure return (by-value structure return) by passing a
> hidden first argument which is a pointer to a structure into which to copy
> the result.  The callee copies the result back through this pointer.
>
> Where these ABIs differ is in returning small structures.  On win32
> structures a power-of-two in size of 8 bytes or less are returned in
> EAX:EDX.  IIRC on linux and mac all structures are returned through the
> hidden first argument pointer.  See
> ThreadedIA32FFIPlugin>>returnStructInRegisters:
>
on macs (at least what gcc generates) it also returns structs <=8
bytes size in registers:


so , currently i implemented it like that:
if sizeof(struct) <= 8 then i assume function returns it in EAX: EDX
otherwise via hidden pointer.

>>
>>
>> It is easy to add support for that, but to make it work correctly can
>> be tricky.
>> See this, for example:
>>
>> http://stackoverflow.com/questions/161788/are-there-any-downsides-to-passing-structs-by-value-in-c-rather-than-passing-a
>>
>>
>> >>
>> >>
>> >> so, what you do is to change the return value to simple void*
>> >> and then copy the contents of struct into instance of corresponding
>> >> NBExternalStructure subclass
>> >> using #fromPointer: method.. to conveniently access its fields values.
>> >
>> >
>> > yes I saw that in NB tests.
>> >
>> >>
>> >>
>> >>
>> >> but this is in general, in your case this function is actually inlined
>> >> by compiler (as CV_INLINE suggests), so there could be even no
>> >> exported symbol for it in dynamic library.
>> >> and the function is actually so simple, that you don't need to wrap it
>> >> at
>> >> all.
>> >> you can just create a subclass of NBExternalStructure , named CvSize,
>> >> implement fieldDesc method as:
>> >>
>> >> fieldsDesc
>> >> ^ #(
>> >> int width;
>> >> int height
>> >> )
>> >>
>> >>
>> >> and if you invoke:
>> >>
>> >> CvSize new width: 1 height:2
>> >>
>> >> it will be equivalent as if you will call cvSize(1,2) function.
>> >
>> >
>> > yes it is exactly what I did.
>> >
>> > So my problem is:
>> >
>> > NBCvSize implemented as a subclass of NBExternalStruct with fieldDesc
>> > correctly set up.
>> > Then wrap the function cvGetSize:
>> >
>> > getSize
>> >       self nbCall: #(NBCvSize cvGetSize(IplImage self)) module: LIB_CV.
>> >
>> > But I get a debugger because:
>> >
>> > NBExternalStruct>>coerceReturn: gen
>> > " ... should we support handling return of external structures? "
>> > self error: 'returning pointer to structure?'
>> >
>> > And I have no idea how to implement this (black magic EAX pop push ;-))
>> > to
>> > coerce result of struct.
>> >
>>
>>
>> you don't. if function takes an implicit struct pointer, you can just
>> rewrite the function signature from
>> NBCvSize cvGetSize(IplImage self)
>> to:
>>
>> void cvGetSize(NBCvSize hidden, IplImage self)
>>
>> and so, you pass a fresh instance of NBCvSize as argument, which
>> function then fill.
>> But if C compiler using registers to return struct.. then you're screwed
>> :)
>>
>> Anyways, Luc i will try to read docs about C ABI and see if we can
>> easily add support for that.
>>
>> --
>> Best regards,
>> Igor Stasenko.
>>
>
>
>
> --
> best,
> Eliot
>



-- 
Best regards,
Igor Stasenko.
typedef struct { int x; int y; } foos;

 foos foo ()
{
    foos bar = {20 , 100 };
    return bar;
    
    
}


typedef struct { char x; char y; } foo2;

foo2 b ()
{
    foo2 bar = {20 , 100 };
    return bar;
    
    
}


typedef struct { int a1; int a2; char a3; } foo3;


foo3 c () __attribute__ ((noinline));

foo3 c (int ss, int fff, int yyy)
{
    foo3 bar = {20 , 100, 40 };
    return bar;
    
    
}



foo3 d ()
{
    
    
    
    foo3 rr = c(1,2,3);
    return rr;
}

Attachment: test.s
Description: Binary data

Reply via email to