В чем причина ошибок компиляции из .h файла пользовательского класса библиотеки в Arduino IDE - PullRequest
0 голосов
/ 16 мая 2018

Я разрабатываю программу для робота с использованием 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;
}

Затем я импортирую библиотеку на Arduino с #include <Position.h> и затем инициализирую ее:

Position position(Variable1,Variable2);

Но когда я хочу использовать его и Energia (или Arduino), я получаю следующие ошибки:

In file included from C:\Users\alex9\Documents\Energia\sketch_may10a\sketch_may10a.ino:1:0:
C:\Users\alex9\Documents\Energia\libraries\Position/Position.h:15:18: error: expected unqualified-id before 'int'
         Position(int PinEcho, int PinTrig);
                  ^
C:\Users\alex9\Documents\Energia\libraries\Position/Position.h:15:18: error: expected ')' before 'int'
C:\Users\alex9\Documents\Energia\libraries\Position/Position.h:13:1: error: an anonymous struct cannot have function members
 {
 ^
C:\Users\alex9\Documents\Energia\libraries\Position/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

Я не понимаю эти сообщения об ошибках и не знаю, что мне нужно исправить,Может ли кто-нибудь мне помочь?

Ответы [ 2 ]

0 голосов
/ 17 мая 2018

Вы не должны называть класс так же, как называете свое определение

Определение похоже на псевдоним, поэтому в качестве имени класса задается значение определения, в вашем случае - пустая строка.

0 голосов
/ 17 мая 2018

В вашем файле .h есть следующие строки текста, которые являются командами препроцессора:

  • проверить, определен ли макрос препроцессора "Позиция"
  • , если онне определено, тогда определите его как пустой или без текста

Как только препроцессор делает это определение макроса для макроса «Позиция», тогда как препроцессор продолжает выполнять обработку исходного текста, одна из вещей, которые онделает каждый раз, когда находит токен «Позиция», он заменяет этот токен определенным значением, которое в данном случае является пустой строкой.

#ifndef Position
#define Position

При использовании препроцессора вы должны помнить, что это дополнительная обработка.шаг, который не имеет ничего общего с компиляцией.Это только этап обработки текста, который используется для изменения исходного текста перед его подачей в компилятор, что является совершенно отдельным этапом.

Вы можете проверить, что происходит, запустив препроцессор и посмотрев на него.результирующий выходной файл.То, как это сделать, зависит от компилятора, хотя обычно это переключение компилятора.

Типичный способ поместить защиту препроцессора в файл .h - выполнить что-то вроде этого примера.Этот макрос препроцессора для защиты включаемого файла состоит из имени включаемого файла, за которым следует буква «H», за которой следует слово «включено» с различными частями, связанными с подчеркиванием:

#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 сделают что-то подобное для вас в процессе создания исходного кода для классов и тому подобного.Вот пример из более старой IDE Visual Studio C ++, которая генерировала включаемый файл класса MFC.Это своего рода излишество в том смысле, что кажется, что IDE генерирует GUID, который является довольно уникальным, и использует его для создания того, что похоже на 99,9999999999% вероятного уникального имени или идентификатора макроса препроцессора.Обратите внимание, что при создании этого имени макроса в среде IDE использовалось имя включаемого файла, буква «H» и слово «включенный» вместе с 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 для получения дополнительной информации о препроцессоре.Этот материал также должен применяться к большинству версий препроцессора на С ++.

...