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.

Reply via email to