On 17 Feb 2018, at 02:50, Ben Coman <btc@openInWorld.com> wrote:On 16 February 2018 at 16:38, Esteban Lorenzano <estebanlm@gmail.com> wrote:hi,
���casting��� is not necessary in general since is just a way to tell the C compiler that a pointer is form a certain type (but is always a pointer, and in machine code is always the same).
So, here you will do something like this:
Iterator >> asCollectionOfType: aTypeName
�� �� �� �� | result address typeClass |
�� �� �� �� result := OrderedCollection new.
�� �� �� �� address := ExternalAddress new.
�� �� �� �� typeClass := FFIExternalType resolveType: aTypeName.
�� �� �� �� [self iterator_next: address]
�� �� �� �� �� �� �� �� whileTrue: [ result add: (typeClass fromHandle: address) ].Perhaps this is a bit about discover-ability.����People with C experience maynaturally search for "cast".�� If I Spotter search for..... cast #iit turns up only four... "broadcast" under Socket classIf that was instead like...�� (typeClass castFromHandle: address)then people may be more likely to find it themselves.I was thinking to implement the #castTo: for all the ���pointer��� classes (ByteArray, FFIExternalReference, FFIExternalStructure).��#[42 0 0 0] castTo: FFIInt32 -> 42what do you think?
Estebancheers -ben�������� ��^result
Iterator >> iterator_next: data
�� �� �� �� ^ self ffiCall: #(Boolean iterator_next (Iterator self, void** data))
now��� you have a problem if your type if your type is an ���atomic��� type, like int, long, etc. because those values are passed ���by value��� and not by pointer, so you will need to decode them.
in this case, I would implement a�� method extension (probably it worths to add it to UFFI):
FFIExternalType class >> valueFromHandle: anAddress
�� �� �� �� ^ self new handle: anAddress at: 1 ���This is used for structures, but we can reuse them :)"
FFIExternalReference class >> valueFromHandle: anAddress
�� �� �� �� ^ self fromHandle: anAddress
FFIExternalStructure class >> valueFromHandle: anAddress
�� �� �� �� ^ self fromHandle: anAddress
So your function will be like something like this:
Iterator >> asCollectionOfType: aTypeName
�� �� �� �� | result address typeClass |
�� �� �� �� result := OrderedCollection new.
�� �� �� �� address := ExternalAddress new.
�� �� �� �� typeClass := FFIExternalType resolveType: aTypeName.
�� �� �� �� [self iterator_next: address]
�� �� �� �� �� �� �� �� whileTrue: [ result add: (typeClass valueFromHandle:: address) ].
�� ��^result
and voil��, you have your cast :)
Esteban
ps: (some errors can be found here, since I���m ���programming at mail client���, but you get the idea ;) )
> On 15 Feb 2018, at 19:59, Egor Scorik <shirofaii@gmail.com> wrote:
>
> Hi,
>
> I'm trying to play with new UFFI system. It looks much easier then
> NativeBoost, but unfortunately its hard to find any docs or examples.
> I have problem with casting void* (ExternalAddress) into smalltalk object if
> there is no hardcoded type in ffi method. And I really dislike the idea of
> making many ffi methods, one for each required type.
> In this example i can't understand how to make something like `address
> castTo: type`
>
> FFIExternalObject subclass: #Iterator
>
> Iterator >> asCollectionOfType: aTypeName
>�� �� �� ��| result address type |
>
>�� �� �� ��result := OrderedCollection new.
>�� �� �� ��address := ExternalAddress new.
>�� �� �� ��type := FFIExternalType resolveType: aTypeName.
>�� �� �� ��[self iterator_next: address] whileTrue: [
>�� �� �� �� �� �� �� ��result add: (address castTo: type).
>�� �� �� ��].
>�� �� ^result
>
> Iterator >> iterator_next: data
>�� �� �� ��^ self ffiCall: #(Boolean iterator_next (Iterator self, void** data))
>
>
>
>
> --
> Sent from: http://forum.world.st/Pharo-Smalltalk-Users-f1310670.html
>