On Fri, May 4, 2012 at 6:13 AM, Igor Stasenko <siguctua@gmail.com> wrote:
On 4 May 2012 10:38, Luc Fabresse <luc.fabresse@gmail.com> 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:

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