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 |
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 > |
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 >> > |
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 >>> >> > > |
> 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 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 >>>> >>> >> >> > |
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 >>>>> >>> > |
… 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 >>>>>> >>>> >> > > |
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 >>>>>>> >> > |
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 >>>>>>>> >>> >> > > |
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 >>>>>>>>> >> > |
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 >>>>>>>>>> >>> >> > > |
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 >>>>>>>>>>> >>>> >>> >> >> > |
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 >>>>>>>>>>> >> > |
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 >>>>>>>>>>>> >>> > |
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 |
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 >>>>>>>>>>>>> >>>> >> > |
> 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 reply to this post by Ben Coman
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
|
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 |
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:
|
Free forum by Nabble | Edit this page |