[UFFI] Getting an array of opaque structures filled

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
20 messages Options
Reply | Threaded
Open this post in threaded view
|

[UFFI] Getting an array of opaque structures filled

Julien Delplanque
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 | Threaded
Open this post in threaded view
|

Re: [UFFI] Getting an array of opaque structures filled

EstebanLM
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 <[hidden email]> 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 | Threaded
Open this post in threaded view
|

Re: [UFFI] Getting an array of opaque structures filled

Julien Delplanque
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 <[hidden email]> 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 | Threaded
Open this post in threaded view
|

Re: [UFFI] Getting an array of opaque structures filled

EstebanLM
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

… 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 <[hidden email]> 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 <[hidden email]> 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 | Threaded
Open this post in threaded view
|

Re: [UFFI] Getting an array of opaque structures filled

EstebanLM

> On 01 Jul 2016, at 12:27, Esteban Lorenzano <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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 | Threaded
Open this post in threaded view
|

Re: [UFFI] Getting an array of opaque structures filled

Julien Delplanque
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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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 | Threaded
Open this post in threaded view
|

Re: [UFFI] Getting an array of opaque structures filled

EstebanLM
… 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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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 | Threaded
Open this post in threaded view
|

Re: [UFFI] Getting an array of opaque structures filled

Julien Delplanque
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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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 | Threaded
Open this post in threaded view
|

Re: [UFFI] Getting an array of opaque structures filled

EstebanLM
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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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 | Threaded
Open this post in threaded view
|

Re: [UFFI] Getting an array of opaque structures filled

Julien Delplanque
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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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 | Threaded
Open this post in threaded view
|

Re: [UFFI] Getting an array of opaque structures filled

EstebanLM
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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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 | Threaded
Open this post in threaded view
|

Re: [UFFI] Getting an array of opaque structures filled

EstebanLM
ok, can you reload development version and try again?

ps: this is easier on slack ;)

> On 01 Jul 2016, at 14:00, Esteban Lorenzano <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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 | Threaded
Open this post in threaded view
|

Re: [UFFI] Getting an array of opaque structures filled

Julien Delplanque
In reply to this post by EstebanLM
No problem, give me as much version(s) to test as you want. :p

Julien


On 01/07/16 14:00, Esteban Lorenzano 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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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 | Threaded
Open this post in threaded view
|

Re: [UFFI] Getting an array of opaque structures filled

Julien Delplanque
In reply to this post by EstebanLM
And it works!

Thanks a lot!

Yes I should join slack, do I need an invitation or something?

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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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 | Threaded
Open this post in threaded view
|

Re: [UFFI] Getting an array of opaque structures filled

Julien Delplanque
In reply to this post by EstebanLM
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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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
>>>>>>>>>>>>
>>>
>


=?UTF-8?Q?Capture_d'=c3=a9cran_de_2016-07-04_10-17-18.png?= (122K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [UFFI] Getting an array of opaque structures filled

Ben Coman
How does it compare with the result you get in pure C?
e.g. using this code...
http://libusb.org/browser/libusb/examples/lsusb.c?rev=efc29733ad31f81883a7ac51a6cc6cda9ad4feb9&order=name

On Mon, Jul 4, 2016 at 4:24 PM, Julien Delplanque <[hidden email]> wrote:

> 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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]>
>>>>>>>> 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 <[hidden email]>
>>>>>>>>>> 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 <[hidden email]>
>>>>>>>>>>> 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 <[hidden email]>
>>>>>>>>>>>>> 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 | Threaded
Open this post in threaded view
|

Re: [UFFI] Getting an array of opaque structures filled

Ben Coman
> On Mon, Jul 4, 2016 at 4:24 PM, Julien Delplanque <[hidden email]> wrote:
>> 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 Mon, Jul 4, 2016 at 6:15 PM, Ben Coman <[hidden email]> wrote:
> How does it compare with the result you get in pure C?
> e.g. using this code...
> http://libusb.org/browser/libusb/examples/lsusb.c?rev=efc29733ad31f81883a7ac51a6cc6cda9ad4feb9&order=name
>

Also, what is the return value of calling libusb_init() from Pharo?

cheers -ben

Reply | Threaded
Open this post in threaded view
|

Re: [UFFI] Getting an array of opaque structures filled

EstebanLM
In reply to this post by Ben Coman

On 04 Jul 2016, at 12:15, Ben Coman <[hidden email]> wrote:

How does it compare with the result you get in pure C?
e.g. using this code...
http://libusb.org/browser/libusb/examples/lsusb.c?rev=efc29733ad31f81883a7ac51a6cc6cda9ad4feb9&order=name

yes, this is a good approach since I cannot know what is happening… and basically arrays just take the pointer and do “address+offset” to give you another pointer. 
but of course, it can fail… if somewhere there is a problem in function translation…

Esteban



On Mon, Jul 4, 2016 at 4:24 PM, Julien Delplanque <[hidden email]> wrote:
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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]>
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 <[hidden email]>
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 <[hidden email]>
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 <[hidden email]>
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 | Threaded
Open this post in threaded view
|

Re: [UFFI] Getting an array of opaque structures filled

Julien Delplanque
In reply to this post by Ben Coman


On 04/07/16 12:18, Ben Coman wrote:

>> On Mon, Jul 4, 2016 at 4:24 PM, Julien Delplanque <[hidden email]> wrote:
>>> 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 Mon, Jul 4, 2016 at 6:15 PM, Ben Coman <[hidden email]> wrote:
>> How does it compare with the result you get in pure C?
>> e.g. using this code...
>> http://libusb.org/browser/libusb/examples/lsusb.c?rev=efc29733ad31f81883a7ac51a6cc6cda9ad4feb9&order=name
>>
> Also, what is the return value of calling libusb_init() from Pharo?
>
> cheers -ben

In pure C, it works. All my device are listed with the code at the link
you gave me (so there is no NULL pointer).

In Pharo,  libusb_init() returns 0 as expected.

Julien

Reply | Threaded
Open this post in threaded view
|

Re: [UFFI] Getting an array of opaque structures filled

Julien Delplanque

Ok, the problem is resolved thanks to Esteban.

There was a mistake in the code given in preceding mails so, I am rewriting the 3 steps here:

===

1) Declare your class that subclasses FFIOpaqueObject:


FFIOpaqueObject subclass: USBDevice
    etc...

2) Get a pointer to the array:

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

with:

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

3) Now that we have the size of the array, we can declare it:

array := FFIExternalArray fromHandle: arrayPtr type: USBDevice size: size.

===

The problem was that I was using #fromPointer:type:size instead of #fromHandle:type:size:.

Thanks again Esteban!

Julien

On 04/07/16 13:15, Julien Delplanque wrote:


On 04/07/16 12:18, Ben Coman wrote:
On Mon, Jul 4, 2016 at 4:24 PM, Julien Delplanque [hidden email] wrote:
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 Mon, Jul 4, 2016 at 6:15 PM, Ben Coman [hidden email] wrote:
How does it compare with the result you get in pure C?
e.g. using this code...
http://libusb.org/browser/libusb/examples/lsusb.c?rev=efc29733ad31f81883a7ac51a6cc6cda9ad4feb9&order=name

Also, what is the return value of calling libusb_init() from Pharo?

cheers -ben

In pure C, it works. All my device are listed with the code at the link you gave me (so there is no NULL pointer).

In Pharo,  libusb_init() returns 0 as expected.

Julien