简体   繁体   中英

How to fix “invalid use of non-static member function” in a library importing another library

I'm writing a library for arduino which at a certain point must call a function after a fixed delay without using the delay function.

Since standard c++ libraries are not included, I have to use arduino libraries, and I opted for FlexiTimer2 which is useful to run a function every X time units (this is just an introduction, the problem is not arduino related but c++ related).

.h file

#ifndef StepperDriverController_h
#define StepperDriverController_h

#include <stdlib.h>
#if ARDUINO >= 100
#include <Arduino.h>
#else
#include <WProgram.h>
#include <wiring.h>
#endif

class StepperDriverController
{
    public:
        StepperDriverController(unsigned char step, unsigned char direction);

        void setPulseWidth(unsigned short width);
        // other methods

    protected:
        void stepPinDown();
        void step(bool blocking = true);

    private:
        unsigned char _pins[2];
        // some attributes
};
#endif

.cpp file

#include "StepperDriverController.h"
#include <Thread.h>

void StepperDriverController::stepPinDown()
{
    digitalWrite(_pins[0], LOW);
    FlexiTimer2::stop();
}

void StepperDriverController::setPulseWidth(unsigned short width)
{
    _pulseWidth = width;
    FlexiTimer2::set(width, 1/1000000, stepPinDown);
}

void StepperDriverController::step()
{
    digitalWrite(_pins[1], _direction ? HIGH : LOW);

    digitalWrite(_pins[0], HIGH);
    FlexiTimer2::start();
}

I get invalid use of non-static member function on code FlexiTimer2::set(width, 1/1000000, stepPinDown); and '_pins' was not declared in this scope on digitalWrite(_pins[0], LOW);

I've read many questions related to this error but couldn't find a way to solve it anyway

EDIT

FlexiTimer should not be instantiated, but used as I did, as shown in an official library example

The FlexiTimer2::set() overload you are trying to use is declared like this:

namespace FlexiTimer2 {
    // ...
    void set(unsigned long units, double resolution, void (*f)());
}

The third argument is void (*f)() . That's a function pointer to a free function returning void and taking no arguments. However, you are passing a member function . This can't work.

Then you attempted to change stepPinDown() from a member function into a free function. This won't work either, since making it a free function prevents it from accessing the members of StepperDriverController .

What you can do instead is pass a lambda that you force to be compatible with a free function (using the + syntax) like this:

FlexiTimer2::set(width, 1/1000000, +[]{ /* your code here */ });

Now the problem is how to get access to a StepperDriverController instance and call stepPinDown() on it. Normally with lambdas, you would simply do a lambda capture of the instance:

[&obj]{ obj.stepPinDown(); }

However, such a lambda can not be passed to a function that expects a function pointer. The + notation in +[]{ /* your code here */ } is just there to make it clear that the lambda must not capture anything. You can omit the + if you don't do a capture; it's purely there as a means of having self-documenting and clearer code.

So since you are not allowed to do a lambda capture, and I do not know the exact internals of your code, it's not clear how to best call stepPinDown() inside the lambda. But it seems that StepperDriverController is a singleton object, meaning there's only ever one instance of it. So you could have a global pointer to that instance and use that in the lambda:

FlexiTimer2::set(width, 1/1000000, +[]{ globalInstance->stepPinDown(); });

I can't tell you what the proper solution is in your case, but this is the gist of it.

There's also an issue that's unrelated to any of this, but it's worth pointing out:

1/1000000

This does not do what you think it does. This is integer division and the result will be 0. You need:

1.0/1000000.0

In order to get 0.000001 as the result.

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