Need help pointing to and dereferencing array of structs from a class!

Status
Not open for further replies.

Slabshaft

Member
I'm feeling totally stuck on this one. Complete brick-wall stuck. I've had success using pointers to regular objects, and pointers to arrays of integers, so this seemed like more of the same but I just cannot get it to compile.

I am creating an instance of a "GUI" class creatively called "gui". Then I need all of the methods of that class to have access to and be able to modify an array of structs declared before setup(). See Step_data sequence[16]=...

My understanding of pointers says I should be creating a pointer of type struct Step_data that points to the first struct of array sequence[16]. Then array arithmetic should be able to iterate the pointer automagically for me. I figured the method I use for arrays should also work for an array of structs, but I'm obviously wrong. On hour 6 of scouring for an answer and failed attempts, I broke down and decided to just ask here.

I absolutely cannot figure out how to get this to compile. It seems like no matter what permutation of syntax elements I mess with, I get something like this:

Code:
src\test.cpp: In member function 'void GUI::updateNote(int, int)':
src\test.cpp:13:22: error: invalid use of incomplete type 'struct Step_data'
   (*data)[step_number].note_number = new_note;
                      ^
In file included from src\test.cpp:2:0:
src\GUI_h.h:8:16: note: forward declaration of 'struct Step_data'
     GUI(struct Step_data (*sequence_ptr)[16]);

Here is the code that generates the above error:

main.cpp (I'm using VS Code + PlatformIO which doesn't use .ino)
Code:
#include <Arduino.h>
#include "GUI_h.h"

struct Step_data {
  int note_number;
  int gate;
  int vel;
  int cv1;
  int note_pos;
  int octave;
};

Step_data sequence[16] = {  
{	48, 	50, 	2047, 	2047, 	5, 	4, 	},	
{	49, 	55, 	1842, 	2252, 	6, 	4, 	},	
{	50, 	60, 	1638, 	2457, 	7, 	4, 	},	
{	51, 	65, 	1433, 	2661, 	8, 	4, 	},	
{	52, 	70, 	1228, 	2866, 	9, 	4, 	},	
{	48, 	75, 	1023, 	3071, 	5, 	4, 	},	
{	48, 	80, 	819, 	3276, 	5, 	4, 	},	
{	55, 	95, 	204, 	3890, 	0, 	4, 	},	
{	56, 	90, 	409, 	3685, 	1, 	4, 	},	
{	57, 	95, 	204, 	3890, 	2, 	4, 	},	
{	58, 	100, 	0, 	4095, 	3, 	4, 	},	
{	59, 	0, 	4095, 	0, 	4, 	4, 	},	
{	60, 	25, 	3071, 	1023, 	5, 	5, 	},	
{	48, 	50, 	2047, 	2047, 	5, 	4, 	},	
{	66, 	75, 	1023, 	3071, 	11, 	5, 	},	
{	48, 	85, 	614, 	3480, 	5, 	4, 	}	};

Step_data (*sequence_ptr)[16] = &sequence;


GUI gui = GUI(sequence_ptr);


void setup() {

  for(int i = 0; i < 16; i++){

    gui.updateNote(i, 48);

  }

}

void loop() {  


}

From the library .cpp file
Code:
#include <Arduino.h>
#include "GUI_h.h"


GUI::GUI(struct Step_data (*sequence_ptr)[16]){

  data = sequence_ptr;

}

void GUI::updateNote(int step_number, int new_note){

  (*data)[step_number].note_number = new_note;


}

From the GUI_h.h file
Code:
#ifndef GUI_h
#define GUI_h

class GUI {

  public:

    GUI(struct Step_data (*sequence_ptr)[16]);
 
    struct Step_data (*data)[16]; 

    void updateNote(int step_number, int new_note);

 
  private:

};


#endif
 
quick look suggests make a named pointer foo and then use foo like below?:
Code:
//Step_data (*sequence_ptr)[16] = &sequence;
[B]Step_data *foo = sequence;[/B]

As created sequence is a pointer to a group of struct Step_data. The [16] size is only needed to allocate memory for the array of struct Step_data. When used with the allocated name sequence[16] the compiler may do some bounds checking - but when using as a pointer it is all up to the code to respect the bounds of the pointer and not sure it cares about [16] to check the math - so it doesn't want to see [16] again.

sequence could be used and passed - if another pointer to that is desire foo above provides that.

Code:
GUI gui = GUI( sequence );

 // or

GUI gui = GUI( foo );
 
Thank you for the help! :cool:
1. Moving the the stuct definition to the top of the header file eliminated the forward declaration error.
2. Understanding that the name of the sequence[16] is a pointer significantly simplified things and worked.

Here is the working code for potential future reference.

Main.cpp
Code:
#include <Arduino.h>
#include "GUI_h.h"

Step_data sequence[16] = {  
{	48, 	50, 	2047, 	2047, 	5, 	4, 	},	
{	49, 	55, 	1842, 	2252, 	6, 	4, 	},	
{	50, 	60, 	1638, 	2457, 	7, 	4, 	},	
{	51, 	65, 	1433, 	2661, 	8, 	4, 	},	
{	52, 	70, 	1228, 	2866, 	9, 	4, 	},	
{	48, 	75, 	1023, 	3071, 	5, 	4, 	},	
{	48, 	80, 	819, 	3276, 	5, 	4, 	},	
{	55, 	95, 	204, 	3890, 	0, 	4, 	},	
{	56, 	90, 	409, 	3685, 	1, 	4, 	},	
{	57, 	95, 	204, 	3890, 	2, 	4, 	},	
{	58, 	100, 	0, 	4095, 	3, 	4, 	},	
{	59, 	0, 	4095, 	0, 	4, 	4, 	},	
{	60, 	25, 	3071, 	1023, 	5, 	5, 	},	
{	48, 	50, 	2047, 	2047, 	5, 	4, 	},	
{	66, 	75, 	1023, 	3071, 	11, 	5, 	},	
{	48, 	85, 	614, 	3480, 	5, 	4, 	}	};

Step_data *sequence_ptr = sequence;

GUI gui = GUI(sequence_ptr);

void updateNote_test(int, int, struct Step_data*);

void setup() {

  Serial.begin(9600);


  for(int i = 0; i < 16; i++){

    gui.updateNote(i, 48);

  }

}

void loop() {  


}

library cpp
Code:
#include <Arduino.h>
#include "GUI_h.h"

GUI::GUI(struct Step_data *sequence_ptr){

  data = sequence_ptr;

}

void GUI::updateNote(int step_number, int new_note){

  data[step_number].note_number = new_note;

}

GUI_h.h
Code:
#ifndef GUI_h
#define GUI_h

struct Step_data {
  int note_number;
  int gate;
  int vel;
  int cv1;
  int note_pos;
  int octave;
};

class GUI {

  public:

    GUI(struct Step_data *sequence_ptr);
 
    struct Step_data *data; 

    void updateNote(int step_number, int new_note);
 
  private:

};


#endif
 
Status
Not open for further replies.
Back
Top