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.

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.

Reply via email to