sometimes this c++ thing is a bit mysterious
I need some help...
I know how to call functions from function pointers passing arguments.
If I want to do the same inside a library I fail to pass arguments.
The real situation is quite complicated,
so I boiled it down to the following test code:
// Test.h
#ifndef TEST_h
#define TEST_h
#include <stdio.h>
#include <stdlib.h>
#include "Arduino.h"
class Test {
public:
 void show_parameter(int p);
 void do_it(int p);
 void (*lib_do_what)(int p);
 void testing(void);
};
#endif TEST_h
// Test.cpp
#include <stdio.h>
#include <stdlib.h>
#include "Arduino.h"
#include <Test.h>
void Test::show_parameter(int p) {
 Serial.print("Test::show_parameter(");
 Serial.print(p);
 Serial.println(')');
}
void Test::do_it(int p) {
 Serial.print("Test::do_it(");
 Serial.print(p);
 Serial.println(')');
 // lib_do_what(p);
 (*lib_do_what)(p);
}
void Test::testing() {
 lib_do_what=(void (*)(int)) &Test::show_parameter;
 for (int i=0; i<3; i++)
  do_it(i);
}
// libraries/Test/examples/test/test.ino
#include <stdio.h>
#include <stdlib.h>
#include "Arduino.h"
#include <Test.h>
Test TEST;
void (*global_do_what)(int);
#define BAUDRATE 115200 // works fine here
void setup() {
 Serial.begin(BAUDRATE); // Start serial communication.
 global_do_what=show_parameter;
 delay(500);
}
void loop() {
 for (int i=0; i<3; i++) {
  Serial.print("calling global do_it("); Serial.print(i); Serial.println(')');
  do_it(i);
 }
 Serial.println("\nStarting TEST.testing()");
 TEST.testing();
 Serial.println("done\n");
 // simple brute force to avoid wdt reset on ESP8266 ;)
 delay(1000); delay(1000); delay(1000); delay(1000); delay(1000);
 delay(1000); delay(1000); delay(1000); delay(1000); delay(1000);
}
void show_parameter(int p) {
 Serial.print("global show_parameter(");
 Serial.print(p); Serial.println(')');
}
void do_it(int p) { global_do_what(p);}
I get the following output (ESP8266, similar result on Arduino Mega).
calling global do_it(0)
global show_parameter(0)
calling global do_it(1)
global show_parameter(1)
calling global do_it(2)
global show_parameter(2)
Starting TEST.testing()
Test::do_it(0)
Test::show_parameter(1075846416)
Test::do_it(1)
Test::show_parameter(1075846416)
Test::do_it(2)
Test::show_parameter(1075846416)
done
How to pass the paramter from Test::do_it(int) to Test::show_parameter?
 lib_do_what=(void (*)(int)) &Test::show_parameter;
This should not compile, or at least generate a serious warning.
lib_do_what is a pointer to a void function taking an int as parameter,
Test::show_parameter is a function taking two parameters, the hidden this pointer and an int.
I was not able to code it in a way that the compiler would accept, trying all sort of things...
I have very similar code (though not for an Arduino) where one class is able to tell another which of its methods to call when the second class needs data from the first class. In all cases, the methods involved are static.
Just because a cast shuts the compiler up does NOT mean that the cast was reasonable.
String someUselessWaste = "Do not use Strings";
String *ptr = &someUselessWaste;
int *pInt = (int *)ptr;
That does NOT make pInt point to anything that can reasonably be interpreted as an int.
You could make void Test::show_parameter(int p) a static function.
You could make void show_parameter(int p) a normal (non class) function.
You could make lib_do_what a pointer to a void Test member function taking one int parameter.
You are right, it does not work.
I will think about and try your suggestions.
And yes, it works fine with normal (non class) functions.
I have used it like this for quite a while, but would like to move it to the library now,
hmm, maybe, must think about.
You seem to be wanting to generate a pointer to a class member function, which c++ does not allow, except for static member functions. Non-static member functions require a pointer (this "this" pointer, which is passed in the hidden first argument to all member functions) to the member data of a specific instance of the class. Without an instance of the class, there is no way to generate that pointer. You can do all kinds of silly things with typecasts that will enable code to compile, but that doesn't mean the code will actually DO what the typecasts suggest. Naming a cat "Fido" does not magically transform that cat into a dog. Typecasts basically tell the compiler "forget what you think you know about this object, and instead let's pretend it is a different type of object altogether". It will let you do that, even when it makes absolutely no functional sense.
RayLivingston:
Non-static member functions require a pointer (this "this" pointer, which is passed in the hidden first argument to all member functions) to the member data of a specific instance of the class. Without an instance of the class, there is no way to generate that pointer.
Hmm, I do not really understand:
There is TEST, instance of class Test.
When you call methods of that class, like show_parameter(), you pass it an argument. The compiler has generated a function that takes two arguments, a pointer to the instance and the argument you supplied. What gets called is not the one argument method. What gets called is the two argument function that the compiler generated.
When you use the static keyword in the method declaration, the compiler does not need to generate another function. It simple uses the function that you defined, that takes only the single argument that you supply.
When you cast a pointer to a function (that the compiler generated) that takes two arguments to a pointer to a function that takes one argument, you can not possibly expect that cast to be meaningful.