Pass a member function pointer to a method of a foreign class (EDB Lib) I'm currently working on my own arduino library and I'm becoming exasperated with the following problem: I want to store data with the extended database library (https://code.google.com/p/arduino-edb/) on a sd card. I tried to follow and adapt the instructions on this page and I gave my custom library a property "File dbFile" as well as a property "EDB db". Additionally I have to pass two function pointers to the constructor of the EDB library. So my custom library got two more properties: a writer and a reader function. My class looks roughly like that:

class myLib
{
   public:
      myLib();
      ~myLib();
      void configWriter( unsigned long address, byte data );
      byte configReader( unsigned long address );
      File dbFile;
      EDB configDB;
}


...so far so good. But here comes the pain in the ... When I'm trying to instantiate a new EDB object in the constructor of my class by passing two pointers to the member functions I'm constantly getting an error. Here is how I call the constructor of the EDB library:

configDB = new EDB( &amp;myLib::configWriter, &amp;myLib::configReader );


I get the following error:


  no matching function for call to 'EDB::EDB()'
  
  [...] note: candidates are:
  
  note: EDB::EDB(void ()(long unsigned int, uint8_t), uint8_t ()(long
  unsigned int))
       EDB(EDB_Write_Handler *, EDB_Read_Handler *);


The prototype of the EDB constructor looks like this:


  EDB(EDB_Write_Handler *, EDB_Read_Handler *);


EDB_Write_Handler and EDB_Read_Handler are defined like so:


  typedef void EDB_Write_Handler(unsigned long, const uint8_t);
  typedef uint8_t EDB_Read_Handler(unsigned long);


So I assume that my constructor call doesn't work because the functions that I'm passing are from a foreign class: (myLib::) and not just ()

I have no idea how to solve that problem. Does someone of you have any idea?

Thanks,
Andy

EDIT:
Here is a Minimal, Complete, and Verifiable example:

myLib.h:

#ifndef myLib_h
#define myLib_h

#include "Arduino.h"
#include &lt;SPI.h&gt;
#include &lt;SD.h&gt;
#include &lt;EDB.h&gt;

#define SD_CS 4
#define SD_SS 10

class myLib
{
  public:
    myLib();
    ~myLib();
    void begin();
    void configWriter( unsigned long address, byte data );
    byte configReader( unsigned long address );
    File dbFile;
    EDB * configDB;

};

#endif


myLib.cpp:

#include "myLib.h"

myLib::myLib( void )
{}

myLib::~myLib()
{}

void myLib::begin()
{
  // Init SD  
  pinMode(SS, OUTPUT);
  SD.begin(SD_CS);

  // Load Config
  configDB = new EDB( &amp;myLib::configWriter, &amp;myLib::configReader );
  dbFile = SD.open("config.db", FILE_WRITE);
}

void myLib::configWriter( unsigned long address, byte data )
{
  dbFile.seek(address);
  dbFile.write(data);
  dbFile.flush();
}

byte myLib::configReader( unsigned long address )
{
  dbFile.seek(address);
  return dbFile.read();
}


Arduino sketch:

#include &lt;SPI.h&gt;
#include &lt;SD.h&gt;
#include &lt;EDB.h&gt;
#include "myLib.h"

myLib* a;

void setup()
{
  a = new myLib();
  a-&gt;begin();
}

void loop()
{
}
The problem here is a common one with C++.  It basically boils down to how C++ handles member functions.

You define a member function as, say,

class myLib {
    void myFunc(int val);
};


When you call the function it's actually not defined as that - it's instead had its definition change to:

void myFunc(myLib *this, int val);


The addition of the myLib *this is an implicit parameter, and it's how C++ keeps track of its object instances when calling different functions.

So a function which expects a parameter of void (*func)(int) won't accept your method because it's actually void (*func)(myLib *, int).  Hence the error you are seeing.

There is no easy, clean, way around it that I have found as yet, I am afraid.  The closest you can do is to move the reader and writer functions outside of your class and store a global pointer to the actual class, something like:

static myLib *globalLib;
void globalConfigWriter( unsigned long address, byte data ) {
    globalLib-&gt;congigWriter(address, data);
}
byte globalConfigReader( unsigned long address ) {
    return globalLib-&gt;configReader(address);
}


Then in the constructor for your lib you can do:

myLib::myLib() {
    globalLib = this;
}


You then register the global reader and writer functions with the EDB constructor instead of the class member functions.

It does have the rather major down-side that there can only be one instance of your class since there is only one global pointer and only one pair of reader / writer functions.  There are ways of supporting a finite number of instances, but it basically involves having a reader/writer pair for each instance and allocating one to an instance when it's constructed and de-allocating it when its destructed.  Keeping track of them and knowing which object is associated with which function pair is tricky at best...