[cffi-devel] Converting foreign structures with CFFI generic functions

Frank Goenninger frgo at me.com
Thu Sep 8 13:07:14 UTC 2011


Hi again!

I'm still stuck with the following C code (simplified):

-X-X-X-

// Now, get the locationID of this device. In order to do this, we need to create an IOUSBDeviceInterface 
// for our device. This will create the necessary connections between our userland application and the 
// kernel object for the USB Device.

kr = IOCreatePlugInInterfaceForService(usbDevice, 
                                       kIOUSBDeviceUserClientTypeID,
                                       kIOCFPlugInInterfaceID,
                                       &plugInInterface, 
                                       &score);

// Use the plugin interface to retrieve the device interface.
res = (*plugInInterface)->QueryInterface( plugInInterface, 
                                          CFUUIDGetUUIDBytes( kIOUSBDeviceInterfaceID ),                                
                                          (LPVOID*) &privateDataRef->deviceInterface );
        
// Now done with the plugin interface.
(*plugInInterface)->Release(plugInInterface);

-X-X-X-

I have translated this to:

-X-X-X-

        (let ((kr nil)
              (res nil)
              (deviceName (cffi:foreign-alloc :char :count 128))
              (deviceNameAsCFString nil)
              (privateDataRef nil)
              (plugInInterface (cffi:foreign-alloc 'IOCFPlugInInterface :count 1))
              (score           (cffi:foreign-alloc 'SInt32 :count 1))
              (locationID           nil))
                  
          (setq kr (io-registry-entry-get-name usb-device
                                               deviceName))
          
          (when (not (eql kr KERN_SUCCESS))
            (setf (cffi:mem-ref deviceName 'io_name_t 0) 0))
                  
          (setq deviceNameAsCFString (cf-string-create-with-c-string
                                      *kCFAllocatorDefault*
                                      (foreign-string-to-lisp deviceName)
                                      (foreign-enum-value '__kCFStringEncoding
                                                          :kCFStringEncodingASCII)))
          
          (setq privateDataRef
                (cffi:foreign-alloc 'MyPrivateData :count 1))
          
          (setf (foreign-slot-value privateDataRef
                                    'MyPrivateData
                                    'deviceName)
                deviceNameAsCFString)
      
          (setq kr (io-create-plug-in-interface-for-service
                    usb-device
                    kIOUSBDeviceUserClientTypeID
                    kIOCFPlugInInterfaceID
                    plugInInterface
                    score))

          (if (not (eql kr kIOReturnSuccess))
                   
              (format *debug-io* "~%*** ERROR: io-create-plug-in-interface-for-service: ~s." kr)          
               
              (progn ;; else
          
                (let ((query-interface-ptr
                       (foreign-slot-value plugInInterface
                                           'IOCFPlugInInterface
                                           'ccag.osx.iokit::QueryInterface))
                      (kIOUSBDeviceInterfaceID-uuid-bytes
                       (cf-uuid-get-uuid-bytes kIOUSBDeviceInterfaceID)))
          
                  (format *debug-io* "~%DEVICE-ADDED: query-interface-ptr = ~s."
                          query-interface-ptr)
              
                  (setq res (foreign-funcall-pointer
                             query-interface-ptr
                             ()
                             :pointer plugInInterface
                             CFUUIDBytes kIOUSBDeviceInterfaceID-uuid-bytes
                             :pointer (foreign-slot-pointer privateDataRef
                                                            'MyPrivateData
                                                            'deviceInterface)))
 ....

-X-X-X-

I get everything ok up until I am trying to call foreign-funcall-pointer ... - for which I have no way to create a call-by-value definition using FSBV.

I am sure I am not seeing the forest for the trees ... My mind seems trying to always do direct translations from C to Lisp where another approach is required ... I am eager to hear your thoughts... Thanks a lot !

Best wishes
  Frank






More information about the cffi-devel mailing list