I am trying to write a library for arduino that (among other things) transmits data to another device over a serial bus. I'm using a union of a struct and a byte array so the users can do things like:

myData.dataStruct.temp = getTemp();

and then later they can just use:

myLib.sendData(data);

So my thought was to have a generic header (default header?) that defined a generic struct and union that users could get started with.

genericDataStruct.h:


#ifndef Use_Custom_Data_Struct // Only use these declarations if no custom data struct

# ifndef DataPacket_generic_h
# define DataPacket_generic_h

typedef struct UserDataStruct_t{
    char            header[NSL_PACKET_HEADER_LENGTH];
    int8_t          b1;       ///<  b1  (Generic packet byte  1 of 35 )
    int8_t          b2;       ///<  b2  (Generic packet byte  2 of 35 )
    int8_t          b3;       ///<  b3  (Generic packet byte  3 of 35 )
    // ... etc
    int8_t          b35;      ///<  b35 (Generic packet byte 35 of 35 )

};


typedef union DataPacket_t {
    UserDataStruct_t payloadData;
    byte Packet[sizeof(UserDataStruct_t)];
};

# endif /* ThinSat_DataPacket_generic_h */

#endif /* Use_Custom_Data_Struct */

The library functions use these typedefs, so currently myLib.h is including genericDataStruct.h

myLib.h:

#include "genericDataStruct.h"

// ... later on

class myLib
{

public:
    myLib();
    bool    sendData(DataPacket_t data);
}

The intent was to let the user do things one of two ways:

Use the generic/default data structure:

#include "myLib.h"

DataPacket_t myData;

// later on

myData.payloadData.b1 = 0xFF;

And then they get on with their life, or...

Use their own semantically relevant data structure:

#define Use_Custom_Data_Struct
#include "customDataStruct.h"
#include "myLib.h"

DataPacket_t myData;

// later on

myData.payloadData.temp = 98.6;

When I try to run this I get compiler errors because of multiple typedef struct UserDataStruct_t in my generic header and the user header...

It looks like I'm barking up the wrong tree here. I think #defines don't get shared between files by the preprocessor? So that probably means that include guards won't really do what I want.

I can't extern a struct declaration/definition (I don't think...) so I'm at a bit of a loss.

If anyone can point me in the right direction, it'd be greatly appreciated. Open to code or architecture changes (any help, really).

1 Answers

0
datafiddler On

genericDataStruct.h:

#ifndef USERSTRUCT
typedef struct UserDataStruct_t{
    char            header[NSL_PACKET_HEADER_LENGTH];
    int8_t          b1;       ///<  b1  (Generic packet byte  1 of 35 )
    int8_t          b2;       ///<  b2  (Generic packet byte  2 of 35 )
    int8_t          b3;       ///<  b3  (Generic packet byte  3 of 35 )
    // ... etc
    int8_t          b35;      ///<  b35 (Generic packet byte 35 of 35 )

};
#endif   
typedef union DataPacket_t {
    UserDataStruct_t payloadData;
    byte Packet[sizeof(UserDataStruct_t)];
};

customDatastruct.h

#define USERSTRUCT
typedef struct UserDataStruct_t{
    char            header[NSL_PACKET_HEADER_LENGTH];
    float           temp;   // assuming byte order and float representation fit
// ...
};

However, sizes of UserDatastruct_t must match, as while compiling myLib.cpp customDatastruct.h is unknown and myLib::sendData simply uses the byte Packet[sizeof(UserDataStruct_t)]; part of the union.