سؤال

I'm trying to use CoreMIDI in a RubyMotion project. Here's a simple example of the code:

clientName = "Client"
clientRef = Pointer.new(:uint)
MIDIClientCreate( clientName, nil, nil, clientRef )

See more detailed code and backtrace in the following gist: https://gist.github.com/4299810

That code results in the following error:

(main)> 2012-12-15 14:43:27.410 core-midi-test[42560:c07] app_delegate.rb:5:in application:didFinishLaunchingWithOptions:': expected instance of Pointer of type^{OpaqueMIDIClient}', got I' (TypeError) 2012-12-15 14:43:27.412 core-midi-test[42560:c07] *** Terminating app due to uncaught exception 'TypeError', reason: 'app_delegate.rb:5:inapplication:didFinishLaunchingWithOptions:': expected instance of Pointer of type ^{OpaqueMIDIClient}', gotI' (TypeError)'

The error is apparently with the fourth argument to MIDIClientCreate. The docs for MIDIClientCreate show:

OSStatus MIDIClientCreate (
   CFStringRef     name,
   MIDINotifyProc  notifyProc,
   void            *notifyRefCon,
   MIDIClientRef   *outClient
);

MIDIClientRef derives from MIDIObjectRef which is defined as a UInt32, so I'm fairly certain that Pointer.new(:uint) is the correct type to use with RubyMotion.

Here is the pertinent portion of the CoreMIDI.bridgesupport file that RubyMotion is using:

<function name='MIDIClientCreate'>
  <arg name='name' type='^{__CFString=}' declared_type='CFStringRef'/>
    <arg name='notifyProc' function_pointer='true' type='^?' declared_type='MIDINotifyProc'>
        <arg type='^{MIDINotification=iI}' declared_type='MIDINotification*' const='true'/>
        <arg type='^v' declared_type='void*'/>
        <retval type='v' declared_type='void'/>
    </arg>
    <arg name='notifyRefCon' type='^v' declared_type='void*'/>
    <arg name='outClient' type='^^{OpaqueMIDIClient}' declared_type='MIDIClientRef*'/>
    <retval type='l' declared_type='OSStatus'/>
</function>

As far as I can tell, the bridgesupport definition should include the necessary plumbing to make the proper conversion. But it's of course, not working.

Is there something wrong with my code or is there something wrong the CoreMIDI.bridgesupport file included with RubyMotion?

هل كانت مفيدة؟

المحلول

I found out by reading the documentation for MacRuby that one can explicitly pass the desired pointer type to the Pointer constructor like so:

clientName = "Client"
clientRef = Pointer.new(MIDIClientRef.type)
MIDIClientCreate( clientName, nil, nil, clientRef )

portName = "Output"
outport = Pointer.new(MIDIPortRef.type)
MIDIOutputPortCreate( clientRef[0], portName, outport )
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top