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