Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 4 of 4

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

Hybrid View

  1. #1
    Junior Member
    Join Date
    Jun 2020
    Posts
    12

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

    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

  2. #2
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    12,692
    quick look suggests make a named pointer foo and then use foo like below?:
    Code:
    //Step_data (*sequence_ptr)[16] = &sequence;
    Step_data *foo = sequence;
    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 );

  3. #3
    Senior Member
    Join Date
    May 2015
    Location
    USA
    Posts
    725
    Move the declaration of "struct Step_data" into the .h file.

  4. #4
    Junior Member
    Join Date
    Jun 2020
    Posts
    12

    Thank you for the help!
    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

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •