Могу ли я написать библиотеку, включающую заголовочный файл по умолчанию, если пользователь не укажет свою собственную? - PullRequest
1 голос
/ 03 мая 2019

Я пытаюсь написать библиотеку для Arduino, которая (помимо прочего) передает данные на другое устройство по последовательной шине.Я использую объединение структуры и байтового массива, чтобы пользователи могли делать такие вещи, как:

myData.dataStruct.temp = getTemp();

, а затем они могут просто использовать:

myLib.sendData(data);

Поэтому я подумал о том, чтобы иметь общий заголовок (заголовок по умолчанию?), Определяющий общую структуру и объединение, с которыми пользователи могут начать работу.

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 */

Библиотечные функции используют эти typedef, поэтому в настоящее время myLib.h включает в себя genericDataStruct.h

myLib.h:

#include "genericDataStruct.h"

// ... later on

class myLib
{

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

Намерение состояло в том, чтобы позволить пользователю делать вещи одним из двух способов:

Использовать общую / стандартную структуру данных:

#include "myLib.h"

DataPacket_t myData;

// later on

myData.payloadData.b1 = 0xFF;

И затем онипродолжать свою жизнь или ...

Использовать собственную семантически релевантную структуру данных:

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

DataPacket_t myData;

// later on

myData.payloadData.temp = 98.6;

Когда я пытаюсь запустить это, я получаю ошибки компилятора, потому чтонескольких typedef struct UserDataStruct_t в моем родовом заголовке и пользовательском заголовке ...

Похоже, я лаю здесь не то дерево.Я думаю, что #defines не распределяются между файлами препроцессором?Так что это, вероятно, означает, что включенные охранники на самом деле не будут делать то, что я хочу.

Я не могу отменить объявление / определение структуры (я не думаю ...), поэтому я немногоутрата.

Если кто-нибудь и укажет мне правильное направление, это будет с благодарностью.Открыт для изменений кода или архитектуры (любая помощь, правда).

1 Ответ

0 голосов
/ 03 мая 2019

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
// ...
};

Однако размеры UserDatastruct_t должны совпадать, так как при компиляции myLib.cpp customDatastruct.h неизвестен иmyLib :: sendData просто использует byte Packet[sizeof(UserDataStruct_t)]; часть объединения.

...