Is there a way to use "functions" as parameters of other functions?

Status
Not open for further replies.

Ghosty

Active member
Greetings people!


I know, the tittle sounds complicatted. Let me explain it with an example:

Let's supose I'm defining a library, and there I got a function like this:

void libFunction(<an external function as parameter>){
// some content
}



And outside of the library, someone needs the function above to execute/check/store_in_array/wathever another one, defined by them. Something like:

void userFunction(){
//yaddayadda
}


And calling it like: libFunction(userFunction());

Is that possible? If is, how? I know a way could be using pointers but no idea how they work with functions adresses :/
 
Greetings people!


I know, the tittle sounds complicatted. Let me explain it with an example:

Let's supose I'm defining a library, and there I got a function like this:

void libFunction(<an external function as parameter>){
// some content
}



And outside of the library, someone needs the function above to execute/check/store_in_array/wathever another one, defined by them. Something like:

void userFunction(){
//yaddayadda
}


And calling it like: libFunction(userFunction());

Is that possible? If is, how? I know a way could be using pointers but no idea how they work with functions adresses :/

I pass functions all the time

lest's make it a little bit more complicated

Code:
typedef void (*fxn)(void *, void *);


void func1(void * c, void *s)
{ int *a = (int*) c;
   int *b = (short*) s;
 // does something with arrays a,b
}

void func2(void *c, void *s)
{ int *a = (int*) c;
   int *b = (short*) s;
 // does something  different with arrays a,b
}


int func0(fxn f, void *c, void *s)
{
    f(c,s);
}

main(void)
{ int aa[10]; bb[20];

  short cc[10; dd[20];

  // call now indirectly the first function
   func0((fxn)func1,(void*) aa, (void*) cc)

 // call now indirectly the second function n
   func0((fxn)func2,(void*)bb, (void*) dd)
}

the example is, obviously not useful, but I pass this way callbacks to device interfaces
 
Umm.... looks kinda complicated.

Someone shown me this: void (* fxn[])(void) = {f1, f2, f3,<etc>};

I supose it's making a function array. No?

So.... if I need to fill an array with them should I do something like this?

Code:
typedef void (*fx)(void);
unsigned int fnAcc = 0;   // functions count
const int max = 10;        // just a random number (or defined by user)
void (* fxn[max])(void);  // defining array

void functionArray(fx f){
   fxn[fnAcc++] = f;
}

And user should define functions like this?

Code:
void function1(){
  //Some code
}

void function2(){
  // Another code
}

void fillArray(void){
   functionArray((fx) function1);
   functionArray((fx) function2);
   // Something else
}

void loop(){
  //Whatever
}

Is that correct? And does that "main" works in Arduino like in C?

Thanks in advance.
 
is the following simple enough?
Code:
typedef int (*fxn) (int,int);

int func1(int a, int b)
{ return a - b;
}

int func2(int a, int b)
{ return a + b;
}

fxn f[]={func1,func2};

void setup() {
  // put your setup code here, to run once:
  if(!Serial);  
}

void loop() {
  // put your main code here, to run repeatedly:

  int a=1, b=2;
  Serial.printf("%d - %d = %d\n\r",a,b,f[0](a,b));
  Serial.printf("%d + %d = %d\n\r",a,b,f[1](a,b));
delay(1000);
}
 
Yeah that's a better example.

Still need to understand few things.

I'm tryinf to test an array asigment:

Code:
typedef void (*fxn) (void);

fxn f[2];
int pos = 0;

void fillArray(fxn fn){
  f[pos] = fn;
  pos++;
}

But it gives me the following error:

Arduino:1.6.7 (Windows 7), TD: 1.27, Placa:"Teensy 3.2 / 3.1, Serial, 96 MHz optimized (overclock), US English"

D:\Bibliotecas\Documents\Arduino\IntervalTimerEx\test1.ino:160:3: warning: "/*" within comment [-Wcomment]
test1:6: error: variable or field 'fillArray' declared void
void fillArray(fxn fn){
^
test1:6: error: 'fxn' was not declared in this scope
exit status 1
'fxn' was not declared in this scope

=/
 
Last edited:
Sorry, needed some time to find the error
Code:
typedef int (*fxn) (int,int);

int func1(int a, int b)
{ return a - b;
}

int func2(int a, int b)
{ return a + b;
}

fxn f[2];
int pos = 0;
void fillArray(fxn fx)
{
  f[pos] = fx;
  pos++;
}

void setup() {
  // put your setup code here, to run once:
  if(!Serial);  

  fillArray((fxn)func1);
  fillArray((fxn)func2);
}

void loop() {
  // put your main code here, to run repeatedly:

  int a=1, b=2;
  Serial.printf("%d - %d = %d\n\r",a,b,f[0](a,b));
  Serial.printf("%d + %d = %d\n\r",a,b,f[1](a,b));
delay(1000);
}

the error was in the line
Code:
 f[pos] = f;
note that you have on both sides "f"
replacing this by
Code:
  f[pos] = fx;
code works
 
Noticed that after posting it. Seems like you dindt notice post was edited xDDDDDD

I changed f for fn. As you can see. Still gives error.

Code:
typedef void (*fxn) (void);

fxn f[2];
int pos = 0;

void fillArray(fxn fn){
  f[pos] = fn;
  pos++;
}

But it gives me the following error:

Arduino:1.6.7 (Windows 7), TD: 1.27, Placa:"Teensy 3.2 / 3.1, Serial, 96 MHz optimized (overclock), US English"

D:\Bibliotecas\Documents\Arduino\IntervalTimerEx\test1.ino:160:3: warning: "/*" within comment [-Wcomment]
test1:6: error: variable or field 'fillArray' declared void
void fillArray(fxn fn){
^
test1:6: error: 'fxn' was not declared in this scope
exit status 1
'fxn' was not declared in this scope



=/
 
try my code and compare to your code
Also, without full code from your side (forum rule) I cannot comment on compiler error.
 
Didnt put rest of the code because they're just different tests that are not even remotely related with this. But I supose that code is affecting everything.


Opened your example in a new file. At least it works as I desired.


Thanks for help.
 
Didnt put rest of the code because they're just different tests that are not even remotely related with this. But I supose that code is affecting everything.


Opened your example in a new file. At least it works as I desired.


Thanks for help.

what Arduino preprocessor does is to shift text around and it may be that other code later on may interfere with compilation.
So best is to start always from scratch when trying to understand and solve a problem.
 
function a() can call function b() and pass the address of some other function as a parameter.
Makes sense only if the the function pointer varies as to which function it points to according to events.
Safest to use a pointer to a function that returns nothing and takes no parameters, i.e., its prototype is void funcx(void);
 
function a() can call function b() and pass the address of some other function as a parameter.
Makes sense only if the the function pointer varies as to which function it points to according to events.
Safest to use a pointer to a function that returns nothing and takes no parameters, i.e., its prototype is void funcx(void);

safest yes, but defining function types with parameters is standard in my applications. OK, all my callback functions are not returning a value but are defined as "void (*fxn) (void*,void*)" where the first parameter point to data to be processed and the second parameter point to a structure containing metadata.
had never a problem with that but allows nice asynchronous cooperative data processing
 
Hey there! It's me again.

Since this thread is about functions and such, I'll make another question:

I got a code like this:

Code:
// #Includes and global vars
IntervalTimer T;

void function(){
  //content
}

//...

void setup(){
  //Some setup content

  T.begin(function, period);
}

void loop(){
  //something
}


But since I need to do a library, I'll need to work with classes. So I'll need something like this:

Code:
class anyName{
  // Some vars
  IntervalTimer T;

  public:
    void function();
    void fnSetup();
    // other functions
}

//***************

void anyName::function(){
  // content
}

void anyName::fnSetup(){
  // some code
  T.begin(function, period);
}


If "function()" it's an external method then there's no problem using the "T.begin" line. The problem occurrs when "function()" is inside of a class, giving me the following error:

D:\Bibliotecas\Documents\Arduino\IntervalTimerEx\test1.ino: In member function 'void planificador::test()':
test1:19: error: no matching function for call to 'IntervalTimer::begin(<unresolved overloaded function type>, int)'

slowdownHeartBeat.begin(planner, 1000000);

Overloaded why? I'm just trying to call a function that's inside of a class. Should work. However, it gives me some "candidates":

D:\Bibliotecas\Documents\Arduino\IntervalTimerEx\test1.ino:19:42: note: candidates are:
In file included from D:\Respaldo D\Material del Post Grado\12 - Trabajo de Grado\Información\arduino-1.6.7\hardware\teensy\avr\cores\teensy3/WProgram.h:38:0,
from D:\Respaldo D\Material del Post Grado\12 - Trabajo de Grado\Información\arduino-1.6.7\hardware\teensy\avr\cores\teensy3/Arduino.h:1,
from C:\Users\Dulmy\AppData\Local\Temp\buildafcebdef408e89cf12203fc1e462051f.tmp\sketch\IntervalTimerEx.ino.cpp:1:
D:\Respaldo D\Material del Post Grado\12 - Trabajo de Grado\Información\arduino-1.6.7\hardware\teensy\avr\cores\teensy3/IntervalTimer.h:60:10: note: bool IntervalTimer::begin(IntervalTimer::ISR, unsigned int)
bool begin(ISR newISR, unsigned int newPeriod) {

No idea what that means. ISR? wth is that?


Thanks in advance.





Edited:


Nevermind, found out this thread that answered this question.
 
Last edited:
Pointer to non-static member function is a different type than pointer to function.
Pointer ro static member function is compatible though.
If you need the "this" then use a pure abstract class with a single member function as a base class and pass that along instead.
Or pass "this" and make the member call directly, if you only have one use.
 
Status
Not open for further replies.
Back
Top