On 18 February 2018 at 01:46, Esteban Lorenzano <esteba...@gmail.com> wrote:
> > > On 17 Feb 2018, at 02:50, Ben Coman <b...@openinworld.com> wrote: > > > > On 16 February 2018 at 16:38, Esteban Lorenzano <esteba...@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 > may > naturally search for "cast". If I Spotter search for..... cast #i > it turns up only four... "broadcast" under Socket class > > If 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 -> 42 > > what do you think? > That will be useful, and intuitive for people to find. cheers -ben > > Esteban > > > > cheers -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 <shirof...@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 >> > >> >> >> > >