Access a struct passed in the constructor

Hi friends.
Today I'm trying to create a small library to deal with a MAX485 in a simple way and I need to pass a structure on the constructor, like a payload so when I want to send some data all I need is to fill the structure fields and send it.I wrote all the code but for testing purpose when I try to access a field from the structure passed by reference,just for testing purpose I get an error.

RS485.h:13:71: error: forward declaration of ‘struct Payload’
RS485(uint8_t hardwareControlPin,unsigned char slaveID,struct Payload *userPayload);

My class consist in some iVars represented like this:

   struct PACKET
   {
       uint8_t startByte;
       uint8_t slaveID ;
       struct Payload *userData;
       uint8_t crc ;
   };
  
  uint8_t transceiverPin;//max485 Control Pin 
  PACKET frame; //A struct variable that contains a pointer to a struct of type Payload

My constructor I have this:

RS485::RS485(uint8_t hardwareControlPin,unsigned char slaveID,struct Payload *userPayload)
{
  transceiverPin = hardwareControlPin;
  pinMode(transceiverPin, OUTPUT);//Pin that Control Data Direction
  digitalWrite(transceiverPin,LOW);//Set the default state to listen

  //Build the payload
  frame.startByte = headerByte;
  frame.slaveID = slaveID;
  frame.userData = userPayload;
  frame.crc = '9';//Dummy value for now
  
  //Test the passed struct userPayload
  Serial.println(frame.startByte); //This prints ok
  Serial.println(frame.userPayload->one);//with this it does not compile
}

My goal is to pass a struct created before void setup() and then pass it by reference using:

#include "RS485.h"
struct Payload
{
uint8_t one;
char name;
bool boolVariable;
int var1;
float var2;
double var3;
};

Payload myPayload;

void setup()
{
Serial.begin(9600);
RS485 max485(13,'2',&myPayload);//I pass the address of the myPayload to the constructor

This should pass the address of myPayload and assign it on the constructor to the instance variable frame.userData. .I do this in this line on the constructor:

frame.userData = userPayload;

Then I cant print the values passed not sure why.The fact is I have a structure inside a structure and using the
Serial.println(frame.userPayload->one) does not compile.
If I comment this line it compiles ok.If I uncomment it I get the error:

RS485.cpp: In constructor ‘RS485::RS485(uint8_t, unsigned char, Payload*)’:
RS485.cpp:21:29: error: invalid use of incomplete type ‘struct Payload’
Serial.println(userPayload->one);
^
In file included from RS485.cpp:1:0:
RS485.h:13:71: error: forward declaration of ‘struct Payload’
RS485(uint8_t hardwareControlPin,unsigned char slaveID,struct Payload *userPayload);

Any help

You're using struct Payload before you're defining it. There are ways around it, but it's actually pointless.

There are only 2 things you really care about when sending the data:

  1. The address of the data
  2. The length of the data

You shouldn't care, in your library, what the structure of the data is.

Just store, in your library, the address of your struct (as a void *), and the size of the data (pass it a second parameter: sizeof(struct Payload)).

Then the only place your struct Payload is defined and used is in your sketch.

Try dropping the & myPayload is already a pointer.

Mark

HugoPT:
This should pass the address of myPayload and assign it on the constructor to the instance variable frame.userData.

Solving these sort of problems is what C++ polymorphism and inheritance was made for. C++ is a superset of C, so a Class can do all a Struct can do and a whole lot more. The Class keyword effectively deprecates the Struct keyword.

So. don't declare a Struct, declare a Class with only properties. You can then derive a Class with only methods, which when instanced, will be created in memory as a struct, followed by a bunch of function pointers.

Here is an example I wrote to encapsulate a UDP message.
http://mssystems.emscom.net/helpdesk/knowledgebase.php?article=53

The Class keyword effectively deprecates the Struct keyword.

Not really, structs and unions have their own differences to a class. If you were to open up an old sketch and replace 'struct' with 'class' you will end up breaking your code.

pYro_65:

The Class keyword effectively deprecates the Struct keyword.

Not really, structs and unions have their own differences to a class.

What would you use a Struct for which you could not use a Class for and why?

I didn't mention Unions. There is a whole debate to be had about using Unions at all.

If you were to open up an old sketch and replace 'struct' with 'class' you will end up breaking your code.

Yes, I was careful to say, "Effectively deprecates." Rather than, equivalent. :wink:

You shouldn't care, in your library, what the structure of the data is.

Just store, in your library, the address of your struct (as a void *), and the size of the data (pass it a second parameter: sizeof(struct Payload)).

Yes you are totally right.That way the code was tied to that structure data which was not good for people want use it.I follow your advise and the problem is fixed following this way.Thanks for all answers

MattS-UK:
What would you use a Struct for which you could not use a Class for and why?

Backwards compatibility with C.

I didn't mention Unions. There is a whole debate to be had about using Unions at all.

I did , because a union is a class defined with the class-key union. Threw it in to stir the pot, even though one class-key may be able to mimic the other, the advantages of each are distinct.

Really, whats the debate.

pYro_65:
Backwards compatibility with C.

We seem to be in violent agreement :slight_smile:

Really, whats the debate.

The disadvantages of Class Vs Union are distinct too. The debate over the use of Unions concerns the clarity of the resultant code. Particularly when it comes to someone else trying to maintain it, a few years down the line.