Frank Goenninger | 25 Aug 19:19 2011

Passing address of pointer

Hi all,

I have a C struct as follows:

(defcstruct MyPrivateData
  (notification       io_object_t)
  (deviceInterface    :pointer) ;; void pointer 
  (deviceName         CFStringRef)
  (locationID         UInt32))

of which the deviceInterface slot is the one I'm interested in. I need to pass the address of the
deviceInterface pointer to a function that sets the pointer to valid device interface struct.

So...

In the sample code from Apple the C function is called like this:

typedef struct MyPrivateData {
    io_object_t		   notification;
    IOUSBDeviceInterface   **deviceInterface;
    CFStringRef		   deviceName;
    UInt32		   locationID;
} MyPrivateData;

IOCFPlugInInterface	**plugInInterface = NULL;
SInt32	 	        score;
HRESULT 		res;

res = (*plugInInterface)->QueryInterface( plugInInterface, 
                                          CFUUIDGetUUIDBytes( kIOUSBDeviceInterfaceID ),
(Continue reading)

Luís Oliveira | 26 Aug 01:20 2011
Picon

Re: Passing address of pointer

Hello Frank,

On Thu, Aug 25, 2011 at 6:19 PM, Frank Goenninger <frgo <at> me.com> wrote:
> In the sample code from Apple the C function is called like this:
>
> typedef struct MyPrivateData {
>    io_object_t            notification;
>    IOUSBDeviceInterface   **deviceInterface;
>    CFStringRef            deviceName;
>    UInt32                 locationID;
> } MyPrivateData;

Why is deviceInterface a pointer to a pointer?

> IOCFPlugInInterface     **plugInInterface = NULL;
> SInt32                  score;
> HRESULT                 res;
>
> res = (*plugInInterface)->QueryInterface( plugInInterface,
>                                          CFUUIDGetUUIDBytes( kIOUSBDeviceInterfaceID ),
>                                          (LPVOID*) &privateDataRef->deviceInterface );

--

-- 
Luís Oliveira
http://r42.eu/~luis/
Frank Goenninger | 26 Aug 11:08 2011

Re: Passing address of pointer

Hello Luís,

Am 26.08.2011 um 01:20 schrieb Luís Oliveira:

> Hello Frank,
> 
> On Thu, Aug 25, 2011 at 6:19 PM, Frank Goenninger <frgo <at> me.com> wrote:
>> In the sample code from Apple the C function is called like this:
>> 
>> typedef struct MyPrivateData {
>>    io_object_t            notification;
>>    IOUSBDeviceInterface   **deviceInterface;
>>    CFStringRef            deviceName;
>>    UInt32                 locationID;
>> } MyPrivateData;
> 
> Why is deviceInterface a pointer to a pointer?

Because Apple designed the interface to calls like GetLocationID in IOKit like this:

kr = (*privateDataRef->deviceInterface)->GetLocationID(privateDataRef->deviceInterface, &locationID);

Here I need to pass the address of a pointer to IOUSBDeviceInterface struct ...

This:

IOReturn (*GetLocationID)(void *self, UInt32 *locationID);

is part of

(Continue reading)

Luís Oliveira | 26 Aug 12:52 2011
Picon

Re: Passing address of pointer

On Fri, Aug 26, 2011 at 10:08 AM, Frank Goenninger <frgo <at> me.com> wrote:
> kr = (*privateDataRef->deviceInterface)->GetLocationID(privateDataRef->deviceInterface, &locationID);
>
> Here I need to pass the address of a pointer to IOUSBDeviceInterface struct ...

Couldn't you call it like this?

  IOUSBDeviceInterface *foo;
  GetLocationID(&foo, ...);

If you can, I'd try reducing your test case to allocate a pointer
using WITH-FOREIGN-OBJECT and pass that to GetLocationID instead of
using a struct.

Cheers,

--

-- 
Luís Oliveira
http://r42.eu/~luis/
Frank Goenninger | 26 Aug 13:03 2011

Re: Passing address of pointer

Am 26.08.2011 um 12:52 schrieb Luís Oliveira:

> On Fri, Aug 26, 2011 at 10:08 AM, Frank Goenninger <frgo <at> me.com> wrote:
>> kr = (*privateDataRef->deviceInterface)->GetLocationID(privateDataRef->deviceInterface, &locationID);
>> 
>> Here I need to pass the address of a pointer to IOUSBDeviceInterface struct ...
> 
> Couldn't you call it like this?
> 
>  IOUSBDeviceInterface *foo;
>  GetLocationID(&foo, ...);
> 
> If you can, I'd try reducing your test case to allocate a pointer
> using WITH-FOREIGN-OBJECT and pass that to GetLocationID instead of
> using a struct.
> 
> Cheers,

And how would the CFFI equivalent to 

>  GetLocationID(&foo, ...);

look like?

I still need the address of a variable that holds a pointer (and not the struct)... 

(with-foreign-object (ptr :pointer)
  ...

?
(Continue reading)

Martin Simmons | 26 Aug 13:13 2011

Re: Passing address of pointer

>>>>> On Thu, 25 Aug 2011 19:19:41 +0200, Frank Goenninger said:
> 
>    (setq res (foreign-funcall-pointer
>                 query-interface-ptr
>                 ()
>                 :pointer plugInInterface
>                 CFUUIDBytes (cf-uuid-get-uuid-bytes
>                                kIOUSBDeviceInterfaceID)
>                 :pointer (foreign-slot-pointer privateDataRef
>                                                'MyPrivateData
>                                                'deviceInterface)))
> ...
> 
> This code "crashes" with signal 100 as reported by AllegroCL in the call to foreign-funcall-pointer ...

I suspect the problem is the UUID argument, not the pointer.

CFUUIDBytes is a struct type, i.e. you need to pass the aggregate by value.
IIRC, CFFI doesn't support that.

__Martin
Luís Oliveira | 26 Aug 13:41 2011
Picon

Re: Passing address of pointer

On Fri, Aug 26, 2011 at 12:13 PM, Martin Simmons <martin <at> lispworks.com> wrote:
> I suspect the problem is the UUID argument, not the pointer.
>
> CFUUIDBytes is a struct type, i.e. you need to pass the aggregate by value.
> IIRC, CFFI doesn't support that.

Correct. There's a work-in-progress integration of FSBV[1] into
CFFI[2] that adds such support via libffi. [1] might be the most
useful to Frank if he's in a hurry.

Cheers,

[1] http://repo.or.cz/w/fsbv.git
[2] https://github.com/cffi/cffi/tree/fsbv

--

-- 
Luís Oliveira
http://r42.eu/~luis/
Liam Healy | 26 Aug 18:19 2011
Picon

Re: Passing address of pointer

On Fri, Aug 26, 2011 at 7:41 AM, Luís Oliveira <luismbo <at> gmail.com> wrote:
On Fri, Aug 26, 2011 at 12:13 PM, Martin Simmons <martin <at> lispworks.com> wrote:
> I suspect the problem is the UUID argument, not the pointer.
>
> CFUUIDBytes is a struct type, i.e. you need to pass the aggregate by value.
> IIRC, CFFI doesn't support that.

Correct. There's a work-in-progress integration of FSBV[1] into
CFFI[2] that adds such support via libffi. [1] might be the most
useful to Frank if he's in a hurry.

Cheers,

[1] http://repo.or.cz/w/fsbv.git
[2] https://github.com/cffi/cffi/tree/fsbv

--
Luís Oliveira
http://r42.eu/~luis/

Just to emphasize, the standalone FSBV works, the integration project is very early and probably doesn't even compile.  The syntax will likely change somewhat when the integration is ready.  I just noticed that the repo.or.cz gitweb page is giving an error so I sent an email to the admins.  There's a mirror at http://common-lisp.net/gitweb?p=projects/gsll/fsbv.git;a=summary;js=1 but it seems to be lagging by one commit.

Liam
_______________________________________________
cffi-devel mailing list
cffi-devel <at> common-lisp.net
http://lists.common-lisp.net/cgi-bin/mailman/listinfo/cffi-devel
Luís Oliveira | 26 Aug 18:51 2011
Picon

Re: Passing address of pointer

On Fri, Aug 26, 2011 at 5:19 PM, Liam Healy <lnp <at> healy.washington.dc.us> wrote:
> Just to emphasize, the standalone FSBV works, the integration project is
> very early and probably doesn't even compile.

BTW, a random unstructured thought: it might be interesting to allow
for different "backends" in the integrated FSBV, such that the
structs-by-value functionality could be supported without libffi in
recent Allegro versions or Lispworks.

Cheers,

--

-- 
Luís Oliveira
http://r42.eu/~luis/
Liam Healy | 27 Aug 18:05 2011
Picon

Converting foreign structures with CFFI generic functions

I'm looking for some clarification of the design and intent of some CFFI definitions. As has been mentioned in another thread, I am working on incorporating my system Foreign Structures By Value, FSBV, into CFFI.  As a first step toward that integration, I have been looking at conversion of objects from CL to foreign and vice versa, with the idea of unifying the approach to include foreign structures.  My goal is to be as consistent with the existing CFFI design as I can be.

My understanding is that CFFI's conversion design is expressed in the generic functions translate-to-foreign, translate-from-foreign, and free-translated-object, to which applications may add methods, and the functions convert-to-foreign and convert-from-foreign to permit the user to make a conversion manually.  At present there are no definitions to convert foreign structures, and I'd like to add that.  I think my approach should be to add methods to translate-*-foreign and free-translated-object, or have defcstruct add the methods when it is expanded.

My thought now is that I should define methods for translate-*-foreign and free-translated-object dispatching on the foreign-struct-type class.  The body will call the same method with the structure name, and applications can define methods eql-specialized on the name.  Does this sound like it will work correctly with CFFI as it exists now, so that I can then introduce the libffi interface for the calls to foreign functions?

Thanks,
Liam

_______________________________________________
cffi-devel mailing list
cffi-devel <at> common-lisp.net
http://lists.common-lisp.net/cgi-bin/mailman/listinfo/cffi-devel

Gmane