Skip to content

Commit 9af27d0

Browse files
authored
Merge pull request #358 from adsr/c_err_copy
Copy error message to `RtMidiWrapper` before it's freed
2 parents 00a2f85 + 49fbb64 commit 9af27d0

2 files changed

Lines changed: 40 additions & 26 deletions

File tree

rtmidi_c.cpp

Lines changed: 39 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ class CallbackProxyUserData
5050
#endif
5151
extern "C" const unsigned int rtmidi_num_compiled_apis;
5252

53+
static void rtmidi_set_error_msg (RtMidiPtr device, const char *err);
54+
5355
/* RtMidi API */
5456
const char* rtmidi_get_version()
5557
{
@@ -102,7 +104,7 @@ void rtmidi_open_port (RtMidiPtr device, unsigned int portNumber, const char *po
102104

103105
} catch (const RtMidiError & err) {
104106
device->ok = false;
105-
device->msg = err.what ();
107+
rtmidi_set_error_msg (device, err.what ());
106108
}
107109
}
108110

@@ -114,7 +116,7 @@ void rtmidi_open_virtual_port (RtMidiPtr device, const char *portName)
114116

115117
} catch (const RtMidiError & err) {
116118
device->ok = false;
117-
device->msg = err.what ();
119+
rtmidi_set_error_msg (device, err.what ());
118120
}
119121

120122
}
@@ -126,7 +128,7 @@ void rtmidi_close_port (RtMidiPtr device)
126128

127129
} catch (const RtMidiError & err) {
128130
device->ok = false;
129-
device->msg = err.what ();
131+
rtmidi_set_error_msg (device, err.what ());
130132
}
131133
}
132134

@@ -137,7 +139,7 @@ unsigned int rtmidi_get_port_count (RtMidiPtr device)
137139

138140
} catch (const RtMidiError & err) {
139141
device->ok = false;
140-
device->msg = err.what ();
142+
rtmidi_set_error_msg (device, err.what ());
141143
return -1;
142144
}
143145
}
@@ -153,7 +155,7 @@ int rtmidi_get_port_name (RtMidiPtr device, unsigned int portNumber, char * bufO
153155
name = ((RtMidi*) device->ptr)->getPortName (portNumber);
154156
} catch (const RtMidiError & err) {
155157
device->ok = false;
156-
device->msg = err.what ();
158+
rtmidi_set_error_msg (device, err.what ());
157159
return -1;
158160
}
159161

@@ -168,21 +170,21 @@ int rtmidi_get_port_name (RtMidiPtr device, unsigned int portNumber, char * bufO
168170
/* RtMidiIn API */
169171
RtMidiInPtr rtmidi_in_create_default ()
170172
{
171-
RtMidiWrapper* wrp = new RtMidiWrapper;
173+
RtMidiWrapper* wrp = new RtMidiWrapper{};
172174

173175
try {
174176
RtMidiIn* rIn = new RtMidiIn ();
175177

176178
wrp->ptr = (void*) rIn;
177179
wrp->data = 0;
178180
wrp->ok = true;
179-
wrp->msg = "";
181+
rtmidi_set_error_msg (wrp, "");
180182

181183
} catch (const RtMidiError & err) {
182184
wrp->ptr = 0;
183185
wrp->data = 0;
184186
wrp->ok = false;
185-
wrp->msg = err.what ();
187+
rtmidi_set_error_msg (wrp, err.what ());
186188
}
187189

188190
return wrp;
@@ -191,28 +193,30 @@ RtMidiInPtr rtmidi_in_create_default ()
191193
RtMidiInPtr rtmidi_in_create (enum RtMidiApi api, const char *clientName, unsigned int queueSizeLimit)
192194
{
193195
std::string name = clientName;
194-
RtMidiWrapper* wrp = new RtMidiWrapper;
196+
RtMidiWrapper* wrp = new RtMidiWrapper{};
195197

196198
try {
197199
RtMidiIn* rIn = new RtMidiIn ((RtMidi::Api) api, name, queueSizeLimit);
198200

199201
wrp->ptr = (void*) rIn;
200202
wrp->data = 0;
201203
wrp->ok = true;
202-
wrp->msg = "";
204+
rtmidi_set_error_msg (wrp, "");
203205

204206
} catch (const RtMidiError & err) {
205207
wrp->ptr = 0;
206208
wrp->data = 0;
207209
wrp->ok = false;
208-
wrp->msg = err.what ();
210+
rtmidi_set_error_msg (wrp, err.what ());
209211
}
210212

211213
return wrp;
212214
}
213215

214216
void rtmidi_in_free (RtMidiInPtr device)
215217
{
218+
if (device->msg)
219+
free (device->msg);
216220
if (device->data)
217221
delete (CallbackProxyUserData*) device->data;
218222
delete (RtMidiIn*) device->ptr;
@@ -226,7 +230,7 @@ enum RtMidiApi rtmidi_in_get_current_api (RtMidiPtr device)
226230

227231
} catch (const RtMidiError & err) {
228232
device->ok = false;
229-
device->msg = err.what ();
233+
rtmidi_set_error_msg (device, err.what ());
230234

231235
return RTMIDI_API_UNSPECIFIED;
232236
}
@@ -246,7 +250,7 @@ void rtmidi_in_set_callback (RtMidiInPtr device, RtMidiCCallback callback, void
246250
((RtMidiIn*) device->ptr)->setCallback (callback_proxy, device->data);
247251
} catch (const RtMidiError & err) {
248252
device->ok = false;
249-
device->msg = err.what ();
253+
rtmidi_set_error_msg (device, err.what ());
250254
delete (CallbackProxyUserData*) device->data;
251255
device->data = 0;
252256
}
@@ -260,7 +264,7 @@ void rtmidi_in_cancel_callback (RtMidiInPtr device)
260264
device->data = 0;
261265
} catch (const RtMidiError & err) {
262266
device->ok = false;
263-
device->msg = err.what ();
267+
rtmidi_set_error_msg (device, err.what ());
264268
}
265269
}
266270

@@ -287,42 +291,42 @@ double rtmidi_in_get_message (RtMidiInPtr device,
287291
}
288292
catch (const RtMidiError & err) {
289293
device->ok = false;
290-
device->msg = err.what ();
294+
rtmidi_set_error_msg (device, err.what ());
291295
return -1;
292296
}
293297
catch (...) {
294298
device->ok = false;
295-
device->msg = "Unknown error";
299+
rtmidi_set_error_msg (device, "Unknown error");
296300
return -1;
297301
}
298302
}
299303

300304
/* RtMidiOut API */
301305
RtMidiOutPtr rtmidi_out_create_default ()
302306
{
303-
RtMidiWrapper* wrp = new RtMidiWrapper;
307+
RtMidiWrapper* wrp = new RtMidiWrapper{};
304308

305309
try {
306310
RtMidiOut* rOut = new RtMidiOut ();
307311

308312
wrp->ptr = (void*) rOut;
309313
wrp->data = 0;
310314
wrp->ok = true;
311-
wrp->msg = "";
315+
rtmidi_set_error_msg (wrp, "");
312316

313317
} catch (const RtMidiError & err) {
314318
wrp->ptr = 0;
315319
wrp->data = 0;
316320
wrp->ok = false;
317-
wrp->msg = err.what ();
321+
rtmidi_set_error_msg (wrp, err.what ());
318322
}
319323

320324
return wrp;
321325
}
322326

323327
RtMidiOutPtr rtmidi_out_create (enum RtMidiApi api, const char *clientName)
324328
{
325-
RtMidiWrapper* wrp = new RtMidiWrapper;
329+
RtMidiWrapper* wrp = new RtMidiWrapper{};
326330
std::string name = clientName;
327331

328332
try {
@@ -331,13 +335,13 @@ RtMidiOutPtr rtmidi_out_create (enum RtMidiApi api, const char *clientName)
331335
wrp->ptr = (void*) rOut;
332336
wrp->data = 0;
333337
wrp->ok = true;
334-
wrp->msg = "";
338+
rtmidi_set_error_msg (wrp, "");
335339

336340
} catch (const RtMidiError & err) {
337341
wrp->ptr = 0;
338342
wrp->data = 0;
339343
wrp->ok = false;
340-
wrp->msg = err.what ();
344+
rtmidi_set_error_msg (wrp, err.what ());
341345
}
342346

343347

@@ -346,6 +350,8 @@ RtMidiOutPtr rtmidi_out_create (enum RtMidiApi api, const char *clientName)
346350

347351
void rtmidi_out_free (RtMidiOutPtr device)
348352
{
353+
if (device->msg)
354+
free (device->msg);
349355
delete (RtMidiOut*) device->ptr;
350356
delete device;
351357
}
@@ -357,7 +363,7 @@ enum RtMidiApi rtmidi_out_get_current_api (RtMidiPtr device)
357363

358364
} catch (const RtMidiError & err) {
359365
device->ok = false;
360-
device->msg = err.what ();
366+
rtmidi_set_error_msg (device, err.what ());
361367

362368
return RTMIDI_API_UNSPECIFIED;
363369
}
@@ -371,12 +377,20 @@ int rtmidi_out_send_message (RtMidiOutPtr device, const unsigned char *message,
371377
}
372378
catch (const RtMidiError & err) {
373379
device->ok = false;
374-
device->msg = err.what ();
380+
rtmidi_set_error_msg (device, err.what ());
375381
return -1;
376382
}
377383
catch (...) {
378384
device->ok = false;
379-
device->msg = "Unknown error";
385+
rtmidi_set_error_msg (device, "Unknown error");
380386
return -1;
381387
}
382388
}
389+
390+
static void rtmidi_set_error_msg (RtMidiPtr device, const char *err)
391+
{
392+
if (device->msg) {
393+
free (device->msg);
394+
}
395+
device->msg = strdup(err);
396+
}

rtmidi_c.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ struct RtMidiWrapper {
4545
bool ok;
4646

4747
//! If an error occurred (ok != true), set to an error message.
48-
const char* msg;
48+
char* msg;
4949
};
5050

5151
//! \brief Typedef for a generic RtMidi pointer.

0 commit comments

Comments
 (0)