Arduino IDE中自定义库类的.h文件编译错误的原因是什么



我正在为使用Energia(Arduino的一个分支)的机器人开发一个程序。我决定创建一个由单个类组成的库来处理位置和距离计算。

当我尝试使用该类时,我看到我不理解的编译器错误。

这是我的.h文件:

#ifndef Position
#define Position
#include "Energia.h"
class Position
{
public:
Position(int PinEcho, int PinTrig);
float getDistance(char* Distance);
float getDistanceMoy(int Nombre,char* unite);
private:
int _pinEcho;
int _pinTrig;
};
#endif

.cpp文件包含:

#include "Energia.h" //Arduino.h if we are using Arduino
#include "Position.h"
Position::Position(int pinEcho,int pinTrig)
{
pinMode(pinEcho, OUTPUT);
pinMode(pinTrig, INPUT);
digitalWrite(pinTrigger, LOW);
int _pinEcho = pinEcho;
int _pinTrig = pinTrig;
const unsigned long MEASURE_TIMEOUT = 25000UL;
const float SOUND_SPEED = 340 / 1000;
}
float Position::getDistance(char* mode){
digitalWrite(pinTrigger, LOW);
digitalWrite(pinTrigger, HIGH);
delayMicroseconds(10);
digitalWrite(pinTrigger, LOW);
long mesure = pulseIn(pinEcho,HIGH,MEASURE_TIMEOUT);
float distance = mesure / 2 * SOUND_SPEED;
if(mode =="cm") distance = distance / 10;
if(mode =="dm") distance = distance / 100;
if(mode == "m") distance = distance / 1000;
return distance;
}
float Position::getDistanceMoy(int maxi,char* mode){
int i=0, j=0;
int distMoy = 0;
while(i != maxi ){
digitalWrite(pinTrigger, LOW);
digitalWrite(pinTrigger, HIGH);
delayMicroseconds(10);
digitalWrite(pinTrigger, LOW);
long mesure = pulseIn(pinEcho,HIGH,MEASURE_TIMEOUT);
float distance = mesure / 2 * SOUND_SPEED;
if(distance != 0){
distMoy += distance;
j++;
}
i++;
}
distMoy = distMoy/j;
if(mode =="cm") distMoy = distMoy / 10;
if(mode =="dm") distMoy = distMoy / 100;
if(mode == "m") distMoy = distMoy / 1000;
return distMoy;
}

然后我使用#include <Position.h>在 Arduino 上导入库,然后对其进行初始化:

Position position(Variable1,Variable2);

但是当我想使用它和Energia(或Arduino)时,我会收到以下错误:

In file included from C:Usersalex9DocumentsEnergiasketch_may10asketch_may10a.ino:1:0:
C:Usersalex9DocumentsEnergialibrariesPosition/Position.h:15:18: error: expected unqualified-id before 'int'
Position(int PinEcho, int PinTrig);
^
C:Usersalex9DocumentsEnergialibrariesPosition/Position.h:15:18: error: expected ')' before 'int'
C:Usersalex9DocumentsEnergialibrariesPosition/Position.h:13:1: error: an anonymous struct cannot have function members
{
^
C:Usersalex9DocumentsEnergialibrariesPosition/Position.h:22:1: error: abstract declarator '<anonymous class>' used as declaration
};
^
sketch_may10a:8: error: expected constructor, destructor, or type conversion before '(' token
Position position(PinEcho,PinTrig);
^
exit status 1 expected constructor, destructor, or type conversion before '(' token

我不明白这些错误消息,也不知道我需要修复什么。有人可以帮助我吗?

在 .h 文件中,您有以下文本行,这些文本行是预处理器命令:

  • 检查是否定义了预处理器宏"位置">
  • 如果未定义,则将其定义为空或无文本

一旦预处理器为宏"Position"执行此宏定义,那么当预处理器继续执行其源文本处理时,它所做的一件事是每次找到标记"Position"时,它都会将该令牌替换为其定义的值,在本例中为空字符串。

#ifndef Position
#define Position

使用预处理器时,您必须记住,这是一个与编译无关的附加处理步骤。这是一个纯文本处理步骤,用于在将源文本输入编译器之前对其进行修改,这是一个完全独立的步骤。

您可以通过自行运行预处理器并查看生成的输出文件来检查正在发生的情况。如何完成此操作将因编译器而异,尽管通常它是一个编译器开关。

将预处理器保护放在 .h 文件中的典型方法是执行类似此示例的操作。这个用于包含文件保护的预处理器宏由包含文件的名称组成,后跟字母"H",后跟单词"include",以及用下划线连接的各个部分:

#ifndef POSITION_H_INCLUDED
#define POSITION_H_INCLUDED

通过使用此宏名称,宏名称与源文件中的某些变量或类或结构名称/标签或其他文本标记之间发生冲突的可能性要小得多。

此命名约定为您做了几件事。

首先,它使用全大写字母,这是预处理器宏名称的事实标准。

其次,它非常能描述这个宏名称的意图。

第三,其他一些文本标记相同的可能性相当小,因此遇到错误的可能性很小。

大型源代码的命名方法

但是,对于大型项目,例如在包含数千个文件的数十万行代码中,可能会对不同库中的不同包含文件使用相同的名称。同样的问题也是为什么namespace概念是用C++发明的。

因此,使用添加到宏名称中的一些附加文本的更复杂的名称会增加宏名称唯一的可能性。一种方法是将库的名称或制造商的名称添加到宏名称中。

#ifndef POSITION_H_INCLUDED_POSITION_LIB_MICHAUD
#define POSITION_H_INCLUDED_POSITION_LIB_MICHAUD

一个简单的方法是将日期和时间添加到宏名称中,如下所示:

#ifndef POSITION_H_INCLUDED_20180517_1021_00
#define POSITION_H_INCLUDED_20180517_1021_00

一些 IDE 会为您执行类似操作,作为为类生成源代码之类的事情的一部分。下面是一个来自较旧的Visual Studio C++ IDE的示例,该示例生成了MFC类包含文件。这有点矫枉过正,因为 IDE 似乎会生成一个非常独特的 GUID,并使用它来创建类似于 99.999999999% 可能是唯一的预处理器宏名称或标识符的内容。请注意,在生成此宏名称的过程中,IDE 使用了包含文件的名称、字母"H"和单词"include"以及 GUID。

#if !defined(AFX_OPOSCASHDRAWER_H__86921069_045D_4880_A41A_5A18F0E5FABD__INCLUDED_)
#define AFX_OPOSCASHDRAWER_H__86921069_045D_4880_A41A_5A18F0E5FABD__INCLUDED_

另请注意,IDE 生成的预处理器指令使用的是defined()运算符。这允许您将更复杂的逻辑操作与预处理器的#if指令一起使用。

有关预处理器的更多详细信息,请参阅此维基百科文章 C 预处理器。此材料也应适用于大多数C++版本的预处理器。

你不应该像命名定义一样命名类

定义就像别名,因此,您的类名被设置为定义值,在您的情况下为空字符串。

相关内容

最新更新