简体   繁体   中英

How To Pass Functions To Class In C++?

So I have been working on an Arduino program that sends MIDI data over USB, and I can't seem to figure out how to pass the function that handles sending of midi data to my main class. It worked at some point but for some reason, it doesn't, and I feel like I have tried every combination of things.

Here is my main file, simplified down to just output the MIDI data over serial:

#include "XiaoPiezoDrum.h"

void sendNoteOn(int note, int velocity, int chan) {
    Serial.printf("WORKS! %d %d %d\n", note, velocity, chan);
};

XiaoPiezoDrum drum(9, 2, 3, 4);

void setup() {
    drum.setNoteComFunctions(sendNoteOn);
}

Here is what that setNoteComFunctions method looks like:

void XiaoPiezoDrum::setNoteComFunctions(const std::function<void(int, int, int)>& onFunc) {
    sendNote = [onFunc](auto && PH1, auto && PH2, auto && PH3) { onFunc(PH1, PH2, PH3); };
}

And here is the relevant parts of the main class definition:

class XiaoPiezoDrum {
public:
    XiaoPiezoDrum();
    XiaoPiezoDrum(int piezoPin, int rPin, int gPin, int bPin);
    void setNoteComFunctions(const function<void(int, int, int)>& onFunc); 
    void RunCycle();

private:
    std::function<void(int, int, int)> sendNote;
}

So everything runs just fine until I call sendNote from within RunCycle , which is just called every loop, and then serial communication just stops suddenly. What am I doing wrong? I also tried using bind instead of a lambda, and the same thing happens. When I just copy the same print statement that is in sendNoteOn in the main file into the lambda in setNoteComFunctions , it prints just fine, so I know the issue is all about linking the function from the main file.

Things I have tried:

  • passing the function in setNoteComFunctions both as a reference and not
  • using bind rather than lambda
  • changing the body of sendNoteOn
  • making the lambda arguments references
  • making the lambda arguments not references
  • returning onFunc in the lambda

I have been banging my head against the keyboard for hours with this. If anybody knows what I'm doing wrong, I'd love an explanation!

EDIT Here is the full code of RunCycle . Many of these variables are instance variables that I left out of the provided class definition, but I know the issue is with the call of sendNote , because if I comment it out, things continue running normally. I have also tried replacing the velocity variable with a fixed integer, and the same thing happened.

void XiaoPiezoDrum::RunCycle() {
    double val = sensor.read();
    val = (val > 0) ? val : 0;
    Serial.println(val);
    unsigned long timeElapsed;
    int velocity;
    MaxVal = (val > MaxVal) ? val : MaxVal;
    trigger = val > THRESHOLD && !triggering;
    if (val > THRESHOLD && !triggering) trigger = true;
    if (trigger) {
        triggerTime = millis();
        trigger = false;
        triggering = true;
        triggerBuffer.clear();
    }
    if (triggering) {
        timeElapsed = millis() - triggerTime;
        if (timeElapsed < SAMPLE_TIME) {
            loopCounter++;
            triggerBuffer.addValue(val);
            Serial.println(val);
        }
        else {
            velocity = map(round(triggerBuffer.getMax()), 0, 300, THRESHOLD, 127);
            Serial.printf("Velocity: %d\n", velocity);
            if (comFunctionsSet) sendNote(40, velocity, 1);
            noteEndTime = millis();
            triggerTime = 0;
            triggerBuffer.clear();
            triggering = false;
            resting = true;
        }
    }
}

jignatius' answer did it! I should have known I could do that!! Thanks!

I just had to replace

void XiaoPiezoDrum::setNoteComFunctions(const std::function<void(int, int, int)>& onFunc) {
    sendNote = [onFunc](auto && PH1, auto && PH2, auto && PH3) { onFunc(PH1, PH2, PH3); };
}

with:

void XiaoPiezoDrum::setNoteComFunctions(const std::function<void(int, int, int)>& onFunc) {
    sendNote = onFunc;
}

So glad to have that solved! Thanks!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM