On Fri, May 4, 2012 at 9:44 AM, Igor Stasenko <[email protected]> wrote:

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

add a test for a structs like
    typedef struct { char a; char b; char c; } threeBytes;
    typedef struct { short a; short b; short c; } sixBytes;

(and 5 & 7).  You should see on Mac and Windows these are not passed back
in registers.


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



-- 
best,
Eliot

Reply via email to