Hello again Esteban, all others, I am still experiencing strange behaviors with the objects in the external array. I get a lot of NULL pointers and some strange addresses (I guess, I am not a C expert) that are close to NULL (see the screenshot attached). These objects make the VM crash (segmentation fault) when I call a function from the libusb binding (for NULL objects it may be ok but what about others?). Some other objects (those with a normal address in the screenshot) work finely with the functions calls using UFFI... This kind of bug is not reported in libusb discussions I found on the internet and I tried an example in C, there is no NULL pointer received from the function (they are not even considered in official examples). So I guess the problem may come from Pharo? Do you have any idea of what it could be? I will be available on Slack all the day if you want. :) Thanks in advance, Julien On 01/07/16 14:03, Esteban Lorenzano wrote:
ok, can you reload development version and try again?
ps: this is easier on slack ;)
On 01 Jul 2016, at 14:00, Esteban Lorenzano <estebanlm@gmail.com> wrote:
yes, I made a mistake⦠the problem of not being capable of test here :(
1 minute.
Esteban
On 01 Jul 2016, at 13:56, Julien Delplanque <julien@tamere.eu> wrote:
Ok, now I get a different exception! :-)
"MessageNotUnderstood: LUDevice class>>fromHandle:"
when executing: "array first."
Where LUDevice is defined like this:
FFIOpaqueObject subclass: #LUDevice instanceVariableNames: '' classVariableNames: '' package: 'LibUsb-Kernel'
Julien
On 01/07/16 13:51, Esteban Lorenzano wrote:
I need you to test :)
can you execute this:
(ConfigurationOfUnifiedFFI project version: #development) load.
and then retry your example?
thanks, Esteban
ps: this became pharo-dev, but well⦠still here :)
On 01 Jul 2016, at 13:48, Julien Delplanque <julien@tamere.eu> wrote:
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 <julien@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 <estebanlm@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 <julien@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 <julien@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