On 24 February 2012 12:10, Jan van de Sandt <[email protected]> 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.
