0

I'm trying to write a library for Arduino using the Wire library. Here's my code:

PiCom.h:

#ifndef PiCom_h
#define PiCom_h

#include "Arduino.h"
#include <Wire.h>
class PiCom
{
public:
    PiCom(int address, int* integers[], double* doubles[]);
    static void onReceiveCallback(int numbytes);
    static void onRequestCallback();
private:
    //Actually arrays of pointers to the data to be sent, has to be declared that way cause the size of the array isn't known at compile time
    int** _integers;
    double** _doubles;

    void onReceive(int numbytes);
    void onRequest();

    static PiCom instance;
};

#endif

PiCom.cpp:

#include "Arduino.h"
#include "PiCom.h"


static void onReceiveCallback(int numbytes)
{

}

PiCom::PiCom(int address, int* integers[], double* doubles[])
{
    _integers = integers;
    _doubles = doubles;

    Wire.begin(address);
    void (*receiveFunction) (int);
    receiveFunction = &PiCom::onReceiveCallback;
    Wire.onReceive(receiveFunction);//Here i get an error
}

I want the constructor to be created when a new instance is created. A mehtod in this object should be called when data is requested or received. When trying to pass onRequest(int) directly to Wire.onRequest(void (*) (int)) an error is thrown. Same happend when saving it to receiveFunction.

This problem was solved by using a static function (onReceiveCallback(int). I wanted this static function to call onRequest(int) in the object saved into PiCom::instance.

But now i'm getting another error:

PiCom\PiCom.cpp.o: In function `PiCom':
C:\Program Files\Arduino\libraries\PiCom/PiCom.cpp:26: undefined reference to `PiCom::onReceiveCallback(int)'
C:\Program Files\Arduino\libraries\PiCom/PiCom.cpp:26: undefined reference to `PiCom::onReceiveCallback(int)'
1

Pointer to a member function is a painful corner of C++ until C++11. This is why when you try to pass an instance method pointer to Wire.onReceive (without the static keyword), you will get an error similar to:

error: ISO C++ forbids taking the address of a bound member function to form a pointer to member function.  Say '&PiCom::onReceiveCallback'

Well, you can't argue with the C++ ISO standard... changing the function to a static one (with external linkage, as they say) is indeed a workaround, as you have found out. For this workaround to compile properly you just need to omit the static keyword from your definition (where it is implemented), and leave your declaration (in the header file) as is:

PiCom.h:

...
static void onReceiveCallback(int numbytes);
...

PiCom.cpp:

void PiCom::onReceiveCallback(int numbytes)
{
    ...
}

By doing this you can pass it to Wire.onReceive without any problem, from the PiCom constructor, as follows:

PiCom::PiCom(int address, int* integers[], double* doubles[])
{
    ...
    Wire.onReceive(&PiCom::onReceiveCallback);
    ...
}
  • 1
    Works as it should. I already noticed that i forgot the "PiCom::" and also figured out that i have to use static only in thüe declaration. But anyways, thank you for the detailed answer. – Geosearchef Dec 30 '14 at 12:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.