C++ 我是否可以编写一个包含默认头文件的库,除非用户指定自己的头文件?

C++ 我是否可以编写一个包含默认头文件的库,除非用户指定自己的头文件?,c++,arduino,header,include,conditional,C++,Arduino,Header,Include,Conditional,我正在尝试为arduino编写一个库,它(除其他外)通过串行总线将数据传输到另一个设备。我使用的是结构和字节数组的并集,因此用户可以执行以下操作: myData.dataStruct.temp=getTemp() 然后,他们就可以使用: myLib.sendData(数据) 所以我的想法是有一个通用头(默认头?),它定义了用户可以开始使用的通用结构和联合 genericDataStruct.h: #include "genericDataStruct.h" // ... later on c

我正在尝试为arduino编写一个库,它(除其他外)通过串行总线将数据传输到另一个设备。我使用的是结构和字节数组的并集,因此用户可以执行以下操作:

myData.dataStruct.temp=getTemp()

然后,他们就可以使用:

myLib.sendData(数据)

所以我的想法是有一个通用头(默认头?),它定义了用户可以开始使用的通用结构和联合

genericDataStruct.h:

#include "genericDataStruct.h"

// ... later on

class myLib
{

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

#ifndef Use_Custom_Data_Struct//仅在没有自定义数据结构时使用这些声明
#ifndef数据包\u通用\u h
#定义数据包\u通用\u h
typedef结构用户数据结构{
字符头[NSL_数据包_头_长度];
int8_t b1;//
库函数使用这些typedef,因此当前myLib.h包括genericDataStruct.h

myLib.h:

#include "genericDataStruct.h"

// ... later on

class myLib
{

public:
    myLib();
    bool    sendData(DataPacket_t data);
}
其目的是让用户通过以下两种方式之一进行操作:

使用通用/默认数据结构:

#include "genericDataStruct.h"

// ... later on

class myLib
{

public:
    myLib();
    bool    sendData(DataPacket_t data);
}
#包括“myLib.h”
数据包\u t myData;
//后来
myData.payloadData.b1=0xFF;
然后他们继续他们的生活,或者

使用他们自己的语义相关数据结构:

#定义使用自定义数据结构
#包括“customDataStruct.h”
#包括“myLib.h”
数据包\u t myData;
//后来
myData.payloadData.temp=98.6;
当我尝试运行此程序时,由于我的泛型标头和用户标头中存在多个
typedef struct UserDataStruct\t
,我会收到编译器错误

看来我找错人了。我认为#预处理器不能在文件之间共享定义?所以这可能意味着包括警卫在内的人不会真正做我想做的事

我不能外接结构声明/定义(我不认为…),所以我有点不知所措

如果有人能给我指出正确的方向,我将不胜感激。开放代码或体系结构更改(任何帮助都可以)。

genericDataStruct.h: 但是,
UserDatastruct\t
的大小必须匹配,因为编译
myLib.cpp
customDatastruct.h时未知,myLib::sendData只使用
字节包[sizeof(UserDataStruct_t)]联合体的一部分。

genericDataStruct.h: 但是,
UserDatastruct\t
的大小必须匹配,因为编译
myLib.cpp
customDatastruct.h时未知,myLib::sendData只使用
字节包[sizeof(UserDataStruct_t)]工会的一部分。

您的代码运行良好。我忘了添加myLib.h包含genericDataStruct.h(需要typedefs)——我将用这个细节更新这个问题。@MoeTheCat只是好奇:为什么
int8\t b1;int8_t b2;int8_t b3。。。int8_t b35
而不是
int8\u t b[35]
?@L.F.这是一个公平的问题。其目的是让结构中的字段具有语义意义,但我无法事先知道用户的意图。因此,我只是使用了那些字段名(在这种通用情况下,这些字段名在语义上是有意义的)来保持用法不变。我想用户也可以写入union的字节数组部分,只需寻址正确的元素,如
myData.packet[35]=0xFF
——希望这在我的代码之外是有意义的brain@MoeTheCat看起来你试图实现的正是模板所解决的问题。你的代码运行良好。我忘了添加myLib.h包含genericDataStruct.h(需要typedefs)——我将用这个细节更新这个问题。@MoeTheCat只是好奇:为什么
int8\t b1;int8_t b2;int8_t b3。。。int8_t b35
而不是
int8\u t b[35]
?@L.F.这是一个公平的问题。其目的是让结构中的字段具有语义意义,但我无法事先知道用户的意图。因此,我只是使用了那些字段名(在这种通用情况下,这些字段名在语义上是有意义的)来保持用法不变。我想用户也可以写入union的字节数组部分,只需寻址正确的元素,如
myData.packet[35]=0xFF
——希望这在我的代码之外是有意义的brain@MoeTheCat看来你想要解决的正是模板所要解决的问题。谢谢你的回答-我试过包括警卫,但我也曾围绕工会宣言这样做过。您的方法符合我的测试项目(这是向前迈出的一大步!)-我会看看是否可以在我的库中使用它。现在我得到了关于UserDataStruct\t的多个typedef的编译器警告,但它确实编译了。关于清除这些警告有什么想法吗?包括顺序事项:在本例中,在使用customDatastruct.hGotcha的每个.cpp中,customDatastruct.h必须位于genericDataStruct之前。这是有道理的,但我认为这让我回到了让用户直接修改库文件的位置,因为myLib.cpp必须包含genericDataStruct.h我认为暂时接受编译器警告是可以接受的。谢谢你的回答——我曾经尝试过包含警卫,但我也在工会声明中这样做过。您的方法符合我的测试项目(这是向前迈出的一大步!)-我会看看是否可以在我的库中使用它。现在我得到了关于UserDataStruct\t的多个typedef的编译器警告,但它确实编译了。有清洁的想法吗