title: "Downcasting" C Structs in Swift
body: <p>Core MIDI is a C API which provides capabilities not found elsewhere.</p>
  
  <p>When the user's MIDI setup changes (e.g. you plugged in a device), there is a notification.</p>
  
  <p>This is the type of the function that is called.</p>
  
  <pre><code>typealias MIDINotifyProc = CFunctionPointer&lt;((UnsafePointer&lt;MIDINotification&gt;, UnsafeMutablePointer&lt;Void&gt;) -&gt; Void)&gt;
  </code></pre>
  
  <p>The first parameter is a MIDINotification struct which looks like this:</p>
  
  <pre><code>struct MIDINotification {
      var messageID: MIDINotificationMessageID
      var messageSize: UInt32
  }
  </code></pre>
  
  <p>You might implement the callback like this:</p>
  
  <pre><code>func MyMIDINotifyProc (np:UnsafePointer&lt;MIDINotification&gt;, refCon:UnsafeMutablePointer&lt;Void&gt;) {        
      var notification = np.memory       
      switch (notification.messageID) {
  
      case MIDINotificationMessageID(kMIDIMsgObjectAdded):
          // In Objective-C you would just do a cast here
          // This is the problem line
          var m = np.memory as MIDIObjectAddRemoveNotification
  </code></pre>
  
  <p>You would look at the messageID member to see what kind of notification you just received. There are several (I'm showing just one). For each kind of notification, you will get a different struct passed in. This is the struct you get when a device has been added or removed:</p>
  
  <pre><code>struct MIDIObjectAddRemoveNotification { 
      var messageID: MIDINotificationMessageID
      var messageSize: UInt32
      var parent: MIDIObjectRef
      var parentType: MIDIObjectType
      var child: MIDIObjectRef
      var childType: MIDIObjectType
  }
  </code></pre>
  
  <p>As you see, this struct has additional info. The "child" might be an endpoint to a device for example, so you need these fields.</p>
  
  <p>The problem is casting from the MIDINotification struct (required by the callback signature) to MIDIObjectAddRemoveNotification. The line I've shown using "as" does not work.</p>
  
  <p>Do you have any suggestions for this sort of "downcasting"?</p>