-1

I have the following class:

MIDIDevice midi;
class ExampleMidi
{
protected:
    void noteOnHandler(byte channel, byte note, byte velocity)
    {
        Serial.print("Note On, ch=");
        Serial.print(channel, DEC);
        Serial.print(", note=");
        Serial.print(note, DEC);
        Serial.print(", velocity=");
        Serial.println(velocity, DEC);
    }
protected:
    void init()
    {
        midi.setHandleNoteOn((void (*)(byte, byte, byte)) & ExampleMidi::noteOnHandler);
    }
}

midi.setHandleNoteOn expect a point to a function, or I would like to pass a method to it. This cast is working, it compile and there is no error during execution but I am getting the following warning:

warning: converting from 'void (ExampleMidi::*)(byte, byte, byte) {aka> void (ExampleMidi::*)(unsigned char, unsigned char, unsigned char)}' to 'void (*)(byte, byte, byte) {aka void (*)(unsigned char, unsigned char, unsigned char)}' [-Wpmf-conversions]        midi.setHandleNoteOn((void (*)(byte, byte, byte)) & ExampleMidi::noteOnHandler);

How can I get rid of this warning?

Alexandre
  • 3,088
  • 3
  • 34
  • 53
  • 1
    the error message does not match the code. What is `IO_Midi` ? – 463035818_is_not_an_ai Mar 19 '22 at 18:40
  • 2
    The cast is suspicious. The fact that it didn't work without the cast hints that you're doing something wrong. – HolyBlackCat Mar 19 '22 at 18:41
  • 6
    `noteOnHandler` is a non-static member function, it is not convertible to `(void (*)(byte, byte, byte)`. I don't know what `DEC` is, but if it is global or some constant, you can try making `noteOnHandler` a `static` member function instead. – François Andrieux Mar 19 '22 at 18:41
  • @463035818_is_not_a_number Sorry, may bad, i had a typo in my example. – Alexandre Mar 19 '22 at 18:41
  • @FrançoisAndrieux you are right, after doing some refactoring, I got rid of the warning. I will post my solution. – Alexandre Mar 19 '22 at 19:07
  • I wonder why someone put a negative point to my question? I am just learning C++ and not everything is obvious or clear to me. And with such thing, I will then be scared to ask C++ question on stackoverflow... – Alexandre Mar 19 '22 at 20:07

1 Answers1

1

Following the comment from @FrançoisAndrieux I managed to get rid of the warning:

void noteOnHandler(byte channel, byte note, byte velocity);

MIDIDevice midi;
class ExampleMidi
{
public:
    void init()
    {
        midi.setHandleNoteOn(noteOnHandler);
    }
    void noteOn(byte channel, byte note, byte velocity)
    {
        Serial.print("Note On, ch=");
        Serial.print(channel, DEC);
        Serial.print(", note=");
        Serial.print(note, DEC);
        Serial.print(", velocity=");
        Serial.println(velocity, DEC);
    }
}

ExampleMidi example;

void noteOnHandler(byte channel, byte note, byte velocity)
{
    example.noteOn(channel, note, velocity);
}

There might be some way to make it better but for the moment it is how I got it to work.

Alexandre
  • 3,088
  • 3
  • 34
  • 53
  • While this should compile, it looks fishy from a design perspective. Why is it acceptable to call `noteOn()` using a different object than the one that set the NoteOn handler? Looks like a bug waiting to happen. If it doesn't matter which object is used to call `noteOn()`, then why is an object required (why is the function not `static`)? If no `ExampleMidi` object is accessed by `NoteOn()`, why is it a member function (maybe to access `DEC`?) instead of, say, a non-member function seen only in the implementation file for `ExampleMidi` (e.g. copy the body of `NoteOn()` into `noteOnHandler()')? – JaMiT Mar 19 '22 at 22:07
  • You are completely right and actually at the beginning I was not using object at all. But I had another issue, something like my compiler could not find a variable, so I solved it by creating an object where I inject this var. At the end I solved an issue by creating another one. Maybe I should step back and try to solve the first problem! Thanks @JaMit for your pertinent comment ;-) – Alexandre Mar 20 '22 at 06:13