Oh, ok :p

Can you notify me know when the bug will be resolved?

Thanks,

Julien


On 01/07/16 13:36, Esteban Lorenzano wrote:
… and now you hit a bug.
bah, an “non implemented feature” :P

I never tested arrays with complex types.
it should not be hard… I will provide a fix.

Esteban


On 01 Jul 2016, at 13:30, Julien Delplanque <jul...@tamere.eu> wrote:

Ok, the ffi call is done without problem with your method thanks. :)

But now that I have the array, when I try to access the first element using:

array first.

I get a exception saying I need to override a method:

"SubclassResponsibility: FFIOpaqueObjectType had the subclass responsibility to 
implement #basicHandle:at:"

I looked at others implementors but I am not sure of how I should override it, 
nor if I should.

Thanks for the time your taking to answer me. :-)

Julien

On 01/07/16 12:29, Esteban Lorenzano wrote:
On 01 Jul 2016, at 12:27, Esteban Lorenzano <esteba...@gmail.com> wrote:

hi,

this is because you want to get an array with opaque objects. Do not let the 
*** confuses you… cwhat you actually want, conceptually is something like this:

*((FFIOpaqueObject*)[])

means: you pass the address of an array of opaque types (who are always 
pointers).

So, what you need to pass is the address of an array… you will need to work a 
bit here, since translation is not automatic.

1) you need to declare your type. Let’ say it will be:

FFIOpaqueObject subclass: USBDevice.

2) then you need to get the pointer to this array. You need to rewrite you code 
as this:

arrayPtr := ExternalAddress new.
size := self getDevice: ctx list: arrayPtr.

getDevice: ctx list: list
        ^ self ffiCall: #(size_t libusb_get_device_list (libusb_context *ctx, 
void **list))

NOTE that we change the type to "void **”. This is because this is what you 
actually want: the array of devices

3) now you will have size and arrayPtr. Then you declare the array:

array := FFIExternalArray fromPointer: arrayPtr type: USBDevice
sorry, this expression (while possible) does not stops in “size”… it has to be 
like this, instead:

array := FFIExternalArray fromPointer: arrayPtr type: USBDevice size: size. “you 
already has the size for the result"

… and you should be able to iterate this array normally :)

let me know if this works for you… I’m “coding in mail client”, so it can fail 
:P

cheers,
Esteban


On 01 Jul 2016, at 12:02, Julien Delplanque <jul...@tamere.eu> wrote:

Thanks, it works I get an instance of FFIOpaqueObject.

But how do I get a specific  libusb_device object from the list?

Thanks again for you quick answer :-).

Julien

On 01/07/16 11:44, Esteban Lorenzano wrote:
Hi,

an opaque structure is not an FFIExternalObject but an FFIOpaqueObject.
in that case, something like (simplified):

ctx := (your context).
list := FFIOpaqueObject new.
size := self getDevice: ctx list: list.

getDevice: ctx list: list
        ^ self ffiCall: #(size_t libusb_get_device_list (libusb_context *ctx, 
FFIOpaqueObject ***list))

should work (note that of course you can make libusb_device an alias for your 
type… that does not matters much, this is just a simplification).

if this does not works, if you can provide me code to reproduce it, I can give 
it a shot and see what happens :)

Esteban

On 01 Jul 2016, at 11:19, Julien Delplanque <jul...@tamere.eu> wrote:

Hello everyone,

I have a question about the UFFI API. I have the following function:

ssize_t libusb_get_device_list (libusb_context *ctx, libusb_device ***list)

where libusb_device is an opaque structure.

I made a type mapping "ssize_t" -> "int" and an object inheriting
from FFIExternalObject for the "libusb_context" (others methods
using it are working).

I can not find how to get an array filled with libusb_device using UFFI from 
Pharo. :-(

Thanks in advance,

Julien





Reply via email to