Passing array of void pointers to class function

Hi
I have and array of void pointers that i want to pass the a function inside a class. To then use the array of pointers inside the class. In the final implementation the class will part of a library, but i hope if i can get it working in this simple form - the solution will be the same. I have tried many variations of * in different places and tried to respond to the changing errors, with no luck. Here is the lattest incarnation of my efforts. Which returns this error:
incompatible types in assignment of 'void ()()' to 'void ( [0])()'

void zero(){
}
void one(){
}
void two(){
}

typedef void (*testList[])();

testList tl = {
  zero,
  one,
  two
};

typedef void (**newList[])();

class cl {
public:
  newList nl;
  void setList(void (*list[])()){
     nl = list; // this throws the error
  };

};

cl foo;

void setup(){
 foo.setList(tl); // this is how i hope to use it
}

void loop(){

}

try this (typed here so not 100% sure I don't have typos)

void zero() {
  Serial.println("ZERO");
}
void one() {
  Serial.println("ONE");
}
void two() {
  Serial.println("TWO");
}

typedef void (*testList)();
const testList tl[] = {zero, one, two};

class cl {
  public:
    const testList* nl;
    void setList(const testList list[]) {
      nl = list;
    };
    void go() {
      for (byte i = 0; i < 3; i++) nl[i]();
    }
};

cl foo;

void setup() {
  Serial.begin(115200);
  foo.setList(tl);
  foo.go();
}

void loop() {}

if all is OK you should see in the Serial Monitor (@ 115200 bauds)

ZERO
ONE
TWO

You have an array of void pointers. I would be seriously interested, why you would want to do that kind of stuff in embedded programming. This is an honest question from an old guy.

this is typically used when you want to have various callbacks from objects depending on what happens, you could think of simple click, double click and triple click on a button class for example

I'll let the OP explain her/his won intent

1 Like

thank you - that works :slight_smile:
Is it really that simple that the arrays need to be constants ? could you explain why this works

Each void is different pattern on an LED installation - so using the array to switch patterns. But the real answer might be because i know no better.

No need to be constant. That would work too

void zero() {
  Serial.println("ZERO");
}
void one() {
  Serial.println("ONE");
}
void two() {
  Serial.println("TWO");
}

typedef void (*testList)();  // EDIT : THIS IS A STUPID TYPE NAME. (thx Jiggy-Ninja)
testList tl1[] = {zero, one, two};
testList tl2[] = {one, two, zero};

class cl {
  public:
    testList* nl;
    void setList(testList list[]) {
      nl = list;
    };
    void go() {
      for (byte i = 0; i < 3; i++) nl[i]();
    }
};

cl foo1,foo2;

void setup() {
  Serial.begin(115200);
  foo1.setList(tl1);
  foo2.setList(tl2);
  foo1.go();
  foo2.go();
}

void loop() {}

Serial Monitor (@ 115200 bauds) will show

ZERO
ONE
TWO
ONE
TWO
ZERO

the reason why I put them constant is because you have to realise that the class is just storing the pointer to the start of the array, not a copy (nor does it know the length). so if you move things around in the array, the order will be changed as well in the class (and if the array goes out of scope, you have a bug)

Each void...

you should see void as a type. What you want to say is function, not void

Ok - now i see what you have done ( i think ) so removing the [] from the typedef and then declaring an array of that type. I can see this simplify things some what.

That is not the only change that was made.

In your code, you have typdefed testList to be an array of function pointers. Then you typedef newList to be an array of pointers to function pointers. These are not the same type. Then in the setList method you are trying to assign a testList value to a newList variable. Since they're not the same type, the compiler stops and complains to you.

You're making thinks more complicated. Don't typedef a list-to-pointers-to-list-of-values, that's too complicated to keep track of. Just typedef the callback function type, and make the individual varables arrays or pointers as necessary. It'll be easier to keep track of what's what like this.

void zero(){
}
void one(){
}
void two(){
}

typedef void (*Callback)();

Callback tl[] = {
  zero,
  one,
  two
};

class cl {
public:
  Callback* nl;
  void setList(Callback list[]){
     nl = list; // this throws the error
  };

};

cl foo;

void setup(){
 foo.setList(tl); // this is how i hope to use it
}

void loop(){

}

Now that I look at it, this is actually equivalent to J-M-L's second post, but because he didn't rename the typedef I didn't notice at first. Don't leave it called a list when you take the list part of it out, dude! It confused me, it's definitely going to confuse other people.

1 Like

You got it :slight_smile:

fair enough, I just corrected the types stuff and left the rest as an exercise to OP :slight_smile:

edited the original post

typedef void (*testList)();  // EDIT : THIS IS A STUPID TYPE NAME. (thx Jiggy-Ninja)

1 Like

Thank you both for your help, despite the use of 'stupid' names.

:smiley: :grimacing:

1 Like

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.