浏览代码

Memory leak fix in CoreMidi and addition of UserData pointer to error callback.

Gary Scavone 11 年之前
父节点
当前提交
2c7a6664d6
共有 2 个文件被更改,包括 18 次插入12 次删除
  1. 10 5
      RtMidi.cpp
  2. 8 7
      RtMidi.h

+ 10 - 5
RtMidi.cpp

@@ -224,7 +224,7 @@ RtMidiOut :: ~RtMidiOut() throw()
 //*********************************************************************//
 //*********************************************************************//
 
 
 MidiApi :: MidiApi( void )
 MidiApi :: MidiApi( void )
-  : apiData_( 0 ), connected_( false ), errorCallback_(0)
+  : apiData_( 0 ), connected_( false ), errorCallback_(0), errorCallbackUserData_(0)
 {
 {
 }
 }
 
 
@@ -232,9 +232,10 @@ MidiApi :: ~MidiApi( void )
 {
 {
 }
 }
 
 
-void MidiApi :: setErrorCallback( RtMidiErrorCallback errorCallback )
+void MidiApi :: setErrorCallback( RtMidiErrorCallback errorCallback, void *userData = 0 )
 {
 {
     errorCallback_ = errorCallback;
     errorCallback_ = errorCallback;
+    errorCallbackUserData_ = userData;
 }
 }
 
 
 void MidiApi :: error( RtMidiError::Type type, std::string errorString )
 void MidiApi :: error( RtMidiError::Type type, std::string errorString )
@@ -248,7 +249,7 @@ void MidiApi :: error( RtMidiError::Type type, std::string errorString )
     firstErrorOccured = true;
     firstErrorOccured = true;
     const std::string errorMessage = errorString;
     const std::string errorMessage = errorString;
 
 
-    errorCallback_( type, errorMessage );
+    errorCallback_( type, errorMessage, errorCallbackUserData_);
     firstErrorOccured = false;
     firstErrorOccured = false;
     return;
     return;
   }
   }
@@ -567,7 +568,8 @@ void MidiInCore :: initialize( const std::string& clientName )
 {
 {
   // Set up our client.
   // Set up our client.
   MIDIClientRef client;
   MIDIClientRef client;
-  OSStatus result = MIDIClientCreate( CFStringCreateWithCString( NULL, clientName.c_str(), kCFStringEncodingASCII ), NULL, NULL, &client );
+  CFStringRef name = CFStringCreateWithCString( NULL, clientName.c_str(), kCFStringEncodingASCII );
+  OSStatus result = MIDIClientCreate(name, NULL, NULL, &client );
   if ( result != noErr ) {
   if ( result != noErr ) {
     errorString_ = "MidiInCore::initialize: error creating OS-X MIDI client object.";
     errorString_ = "MidiInCore::initialize: error creating OS-X MIDI client object.";
     error( RtMidiError::DRIVER_ERROR, errorString_ );
     error( RtMidiError::DRIVER_ERROR, errorString_ );
@@ -580,6 +582,7 @@ void MidiInCore :: initialize( const std::string& clientName )
   data->endpoint = 0;
   data->endpoint = 0;
   apiData_ = (void *) data;
   apiData_ = (void *) data;
   inputData_.apiData = (void *) data;
   inputData_.apiData = (void *) data;
+  CFRelease(name);
 }
 }
 
 
 void MidiInCore :: openPort( unsigned int portNumber, const std::string portName )
 void MidiInCore :: openPort( unsigned int portNumber, const std::string portName )
@@ -852,7 +855,8 @@ void MidiOutCore :: initialize( const std::string& clientName )
 {
 {
   // Set up our client.
   // Set up our client.
   MIDIClientRef client;
   MIDIClientRef client;
-  OSStatus result = MIDIClientCreate( CFStringCreateWithCString( NULL, clientName.c_str(), kCFStringEncodingASCII ), NULL, NULL, &client );
+  CFStringRef name = CFStringCreateWithCString( NULL, clientName.c_str(), kCFStringEncodingASCII );
+  OSStatus result = MIDIClientCreate(name, NULL, NULL, &client );
   if ( result != noErr ) {
   if ( result != noErr ) {
     errorString_ = "MidiOutCore::initialize: error creating OS-X MIDI client object.";
     errorString_ = "MidiOutCore::initialize: error creating OS-X MIDI client object.";
     error( RtMidiError::DRIVER_ERROR, errorString_ );
     error( RtMidiError::DRIVER_ERROR, errorString_ );
@@ -864,6 +868,7 @@ void MidiOutCore :: initialize( const std::string& clientName )
   data->client = client;
   data->client = client;
   data->endpoint = 0;
   data->endpoint = 0;
   apiData_ = (void *) data;
   apiData_ = (void *) data;
+  CFRelease( name );
 }
 }
 
 
 unsigned int MidiOutCore :: getPortCount()
 unsigned int MidiOutCore :: getPortCount()

+ 8 - 7
RtMidi.h

@@ -109,7 +109,7 @@ class RtMidiError : public std::exception
     Note that class behaviour is undefined after a critical error (not
     Note that class behaviour is undefined after a critical error (not
     a warning) is reported.
     a warning) is reported.
  */
  */
-typedef void (*RtMidiErrorCallback)( RtMidiError::Type type, const std::string &errorText );
+typedef void (*RtMidiErrorCallback)( RtMidiError::Type type, const std::string &errorText, void *userData );
 
 
 class MidiApi;
 class MidiApi;
 
 
@@ -161,7 +161,7 @@ class RtMidi
     The callback function will be called whenever an error has occured. It is best
     The callback function will be called whenever an error has occured. It is best
     to set the error callback function before opening a port.
     to set the error callback function before opening a port.
   */
   */
-  virtual void setErrorCallback( RtMidiErrorCallback errorCallback = NULL ) = 0;
+  virtual void setErrorCallback( RtMidiErrorCallback errorCallback = NULL, void *userData = 0 ) = 0;
 
 
  protected:
  protected:
 
 
@@ -322,7 +322,7 @@ class RtMidiIn : public RtMidi
     The callback function will be called whenever an error has occured. It is best
     The callback function will be called whenever an error has occured. It is best
     to set the error callback function before opening a port.
     to set the error callback function before opening a port.
   */
   */
-  virtual void setErrorCallback( RtMidiErrorCallback errorCallback = NULL );
+  virtual void setErrorCallback( RtMidiErrorCallback errorCallback = NULL, void *userData = 0 );
 
 
  protected:
  protected:
   void openMidiApi( RtMidi::Api api, const std::string clientName, unsigned int queueSizeLimit );
   void openMidiApi( RtMidi::Api api, const std::string clientName, unsigned int queueSizeLimit );
@@ -413,7 +413,7 @@ class RtMidiOut : public RtMidi
     The callback function will be called whenever an error has occured. It is best
     The callback function will be called whenever an error has occured. It is best
     to set the error callback function before opening a port.
     to set the error callback function before opening a port.
   */
   */
-  virtual void setErrorCallback( RtMidiErrorCallback errorCallback = NULL );
+  virtual void setErrorCallback( RtMidiErrorCallback errorCallback = NULL, void *userData = 0 );
 
 
  protected:
  protected:
   void openMidiApi( RtMidi::Api api, const std::string clientName );
   void openMidiApi( RtMidi::Api api, const std::string clientName );
@@ -448,7 +448,7 @@ class MidiApi
   virtual std::string getPortName( unsigned int portNumber ) = 0;
   virtual std::string getPortName( unsigned int portNumber ) = 0;
 
 
   inline bool isPortOpen() const { return connected_; }
   inline bool isPortOpen() const { return connected_; }
-  void setErrorCallback( RtMidiErrorCallback errorCallback );
+  void setErrorCallback( RtMidiErrorCallback errorCallback, void *userData );
 
 
   //! A basic error reporting function for RtMidi classes.
   //! A basic error reporting function for RtMidi classes.
   void error( RtMidiError::Type type, std::string errorString );
   void error( RtMidiError::Type type, std::string errorString );
@@ -460,6 +460,7 @@ protected:
   bool connected_;
   bool connected_;
   std::string errorString_;
   std::string errorString_;
   RtMidiErrorCallback errorCallback_;
   RtMidiErrorCallback errorCallback_;
+  void *errorCallbackUserData_;
 };
 };
 
 
 class MidiInApi : public MidiApi
 class MidiInApi : public MidiApi
@@ -547,7 +548,7 @@ inline unsigned int RtMidiIn :: getPortCount( void ) { return rtapi_->getPortCou
 inline std::string RtMidiIn :: getPortName( unsigned int portNumber ) { return rtapi_->getPortName( portNumber ); }
 inline std::string RtMidiIn :: getPortName( unsigned int portNumber ) { return rtapi_->getPortName( portNumber ); }
 inline void RtMidiIn :: ignoreTypes( bool midiSysex, bool midiTime, bool midiSense ) { ((MidiInApi *)rtapi_)->ignoreTypes( midiSysex, midiTime, midiSense ); }
 inline void RtMidiIn :: ignoreTypes( bool midiSysex, bool midiTime, bool midiSense ) { ((MidiInApi *)rtapi_)->ignoreTypes( midiSysex, midiTime, midiSense ); }
 inline double RtMidiIn :: getMessage( std::vector<unsigned char> *message ) { return ((MidiInApi *)rtapi_)->getMessage( message ); }
 inline double RtMidiIn :: getMessage( std::vector<unsigned char> *message ) { return ((MidiInApi *)rtapi_)->getMessage( message ); }
-inline void RtMidiIn :: setErrorCallback( RtMidiErrorCallback errorCallback ) { rtapi_->setErrorCallback(errorCallback); }
+inline void RtMidiIn :: setErrorCallback( RtMidiErrorCallback errorCallback, void *userData ) { rtapi_->setErrorCallback(errorCallback, userData); }
 
 
 inline RtMidi::Api RtMidiOut :: getCurrentApi( void ) throw() { return rtapi_->getCurrentApi(); }
 inline RtMidi::Api RtMidiOut :: getCurrentApi( void ) throw() { return rtapi_->getCurrentApi(); }
 inline void RtMidiOut :: openPort( unsigned int portNumber, const std::string portName ) { rtapi_->openPort( portNumber, portName ); }
 inline void RtMidiOut :: openPort( unsigned int portNumber, const std::string portName ) { rtapi_->openPort( portNumber, portName ); }
@@ -557,7 +558,7 @@ inline bool RtMidiOut :: isPortOpen() const { return rtapi_->isPortOpen(); }
 inline unsigned int RtMidiOut :: getPortCount( void ) { return rtapi_->getPortCount(); }
 inline unsigned int RtMidiOut :: getPortCount( void ) { return rtapi_->getPortCount(); }
 inline std::string RtMidiOut :: getPortName( unsigned int portNumber ) { return rtapi_->getPortName( portNumber ); }
 inline std::string RtMidiOut :: getPortName( unsigned int portNumber ) { return rtapi_->getPortName( portNumber ); }
 inline void RtMidiOut :: sendMessage( std::vector<unsigned char> *message ) { ((MidiOutApi *)rtapi_)->sendMessage( message ); }
 inline void RtMidiOut :: sendMessage( std::vector<unsigned char> *message ) { ((MidiOutApi *)rtapi_)->sendMessage( message ); }
-inline void RtMidiOut :: setErrorCallback( RtMidiErrorCallback errorCallback ) { rtapi_->setErrorCallback(errorCallback); }
+inline void RtMidiOut :: setErrorCallback( RtMidiErrorCallback errorCallback, void *userData ) { rtapi_->setErrorCallback(errorCallback, userData); }
 
 
 // **************************************************************** //
 // **************************************************************** //
 //
 //