Question

I wanted to call the following function from OS X's DVDPlayback framework:

OSStatus DVDGetMediaVolumeCFName (
   CFStringRef *outDiscVolumeCFName
);

Eventually, I came up with the following working code:

framework 'DVDPlayback'
p2 = Pointer.new_with_type('^{__CFString}')
DVDGetMediaVolumeCFName(p2)

But I didn't find the '^{__CFString}' bit in any documentation and only found out what it was really doing afterward (I originally cut and pasted it from an error message). I first tried Pointer.new with both :id and :string with no success.

So my questions are:

  • what's the best way to get this pointer (my way seems ugly)?
  • why didn't Pointer.new(:string) work? I thought String, NSString, and CFString were equivalent
  • where would I have looked to find this info? (I checked the MacRuby site, "macro Pointer" reported "Nothing known about Pointer", ~12 google hits, and "MacRuby: The Definitive Guide")
Was it helpful?

Solution

Although there exists a "toll-free" bridge from NSString to CFStringRef, the same does not apply for NSString* to CFStringRef*, due to the use of ARC (Automatic Reference Counting). Casting a CFStringRef* to NSString* requires the use of __bridge, therefore

Pointer.new(:string)

will not work. Using

Pointer.new_with_type('^{__CFString}')

is the best way get this pointer and the best way to find this information is to view the TypeError that is generated when the incorrect type is chosen. For example:

expected instance of Pointer of type `^{__CFString}', got `*' (TypeError)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top