On 24 February 2012 15:02, Jan van de Sandt <jvdsa...@gmail.com> wrote: > > Thanks for the explanation, it starts to make sense to me now. But when I > change the return type of the first call from "void*" to ICUEnumerationNB I > end up here: > > NBExternalStructureType>>coerceReturn: gen > > " ... should we support handling return of external structures? " > self error: 'returning pointer to structure?' > This happens when you putting a pointer to struct as return value in function signature, which means that you doing something wrong, or modified code in different place.
What i see (in ICU-NativeBoost-Core-jvds.3) is following : nbTestprimOpenTimeZones: anErrorCode <primitive: #primitiveNativeCall module: #NativeBoostPlugin> ^ self nbCall: #( ICUEnumerationNB___>>>>_*__<<<< remove it___ ucal_openTimeZones_48( ICUErrorCodeNB* anErrorCode ) ) and once you will do that, the error you see will go away. but i cannot call the function since i don't have the corresponding library on my machine, have binaries somewhere for download?. > The problem is not so urgent for me anymore because I can work around it > using just NBExternalAddress instances. But off course I'm still curious to > know what's the best way to handle these kind of native calls. > I takes time to get used to it. I know by myself that interfacing with C is confusing, especially when dealing with pointers. > Jan. > > PS: The code is > in http://www.squeaksource.com/ICU.html ICUCalendarNB>>#nbTestAllTimeZones > > > > On Fri, Feb 24, 2012 at 2:35 PM, Igor Stasenko <siguc...@gmail.com> wrote: >> >> On 24 February 2012 12:10, Jan van de Sandt <jvdsa...@gmail.com> wrote: >> > Hi, >> > >> > Well, it works if I don't use the ICUEnumeration class. The first call >> > returns an NBExternalAddress instance. If I pass this instance to the >> > second >> > call than it works fine. The native call looks like this: >> > >> > self nbCall: #( char* uenum_next_48(void* aHandle, nil, ICUErrorCodeNB* >> > anErrorCode ) ) >> > >> > My idea was to use a subclass of NBExternalHandle where I can put all >> > the >> > functions related to this handle. But it stops working when I copy the >> > value >> > from the ExternalAddress to my handle subclass ICUEnumerationNB and use >> > one >> > of these calls: >> > >> > self nbCall: #( char* uenum_next_48(ICUEnumerationNB* aHandle, nil, >> > ICUErrorCodeNB* anErrorCode ) ) >> > >> > or >> > >> > self nbCall: #( char* uenum_next_48(ICUEnumerationNB aHandle, nil, >> > ICUErrorCodeNB* anErrorCode ) ) >> > >> >> Since NBExternalHandle is variable byte class, >> if you pass a pointer to it, like >> ICUEnumerationNB* then FFI will push a pointer to the first indexable >> byte in ICUEnumerationNB instance, >> but not the value of handle stored in this instance. >> In your case, you stored UEnumeration*, but then you pushing >> UEnumeration**, while function expects UEnumeration*. >> >> It is hard to say, why "ICUEnumerationNB aHandle" doesn't works for >> you without looking at code, especially >> that NBExternalAddress is a subclass of NBExternalHandle. >> >> You can try the following: >> >> Since both functions working with same type (UEnumeration*) , you can >> actually treat it as if you would have >> >> typedef UEnumeration* ICUEnumerationNB; >> in C. >> >> So, then just remove '*' everywhere (in function which returns it, and >> in functions where you passing it as argument): >> >> self nbCall: #( ICUEnumerationNB ucal_openTimeZones_48( >> ICUErrorCodeNB* anErrorCode ) ) >> >> and: >> self nbCall: #( char* uenum_next_48(ICUEnumerationNB aHandle, nil, >> ICUErrorCodeNB* anErrorCode ) ) >> >> that should work fine, unless that library doing something strange >> (which also might be the case ;). >> >> P.S. originally, i intentionally raising an error when you passing a >> pointer to NBExternalAddress or Handle types >> (so is allows to pass a just a value, but not a pointer to the value) >> to prevent mistakes like that. >> But some functions actually wanting to get a pointer to the pointer >> (like int** etc), so then they can store a pointer at that pointer, >> and i was added that, because it is convenient. >> >> P.P.S Yo dawg, i put a pointer to that pointer so you can point to >> what it points ;) >> >> -- >> Best regards, >> Igor Stasenko. >> > -- Best regards, Igor Stasenko.