неопределенная ссылка на `PPMintIn::PPMintIn(int)'

Я создаю новую библиотеку, которая будет использовать библиотеку PinChangeInt. Я намерен еще больше упростить повторяющийся код, создав библиотеку. (Это сделано для того, чтобы можно было использовать несколько каналов PPM, не переписывая кучу кода для каждого канала, который я решил добавить.) Поскольку я понимаю ООП, я знал, что могу пойти по пути создания собственной библиотеки.

Проблема, с которой я столкнулся прямо сейчас, заключается в том, что библиотека возвращает неопределенную ссылку. IDE, которую я использую, — это UECIDE с QTcreator на стороне, чтобы помочь мне с моим синтаксисом. Компилятор avr-gcc. Чип представляет собой Arduino Uno. Я получаю сообщение о проблеме

C:...\RCRoomba_TestPulseV2.cpp.o: В функции '__static_initialization_and_destruction_0':
C:...\RCRoomba_TestPulseV2.ino:5: неопределенная ссылка на 'PPMintIn::PPMintIn(int)'
C:...\RCRoomba_TestPulseV2.cpp.o: В функции 'настройка':
C:...\RCRoomba_TestPulseV2.ino:9: неопределенная ссылка на 'PPMintIn::begin()'
Не удалось связать скетч

Я попытался определить переменные в своих файлах h и cpp, но, похоже, это не решило проблему.

Вот код .ino.
по какой-то причине UECIDE не видит библиотеки Pinchange и PPMint

#include "arduino.h"
#include "C:\Users\User\Documents\UECIDE\libraries\PinChangeInt\PinChangeInt.h"
#include "C:\Users\User\Documents\UECIDE\libraries\PPMintIn\PPMintIn.h"

PPMintIn CH1(A0);

void setup(){
    Serial.begin(115200);
    CH1.begin();
}

void loop(){
}

Вот код .cpp

#include "arduino.h"
#include "ppmintin.h"
#include "PinChangeInt.h"
//defined these
volatile int pwm_value = 0; 
volatile int prev_time = 0;
uint8_t latest_interrupted_pin = 0;

PPMintIn::PPMintIn(int pin){
    pinMode(pin, INPUT);\
    digitalWrite(pin, HIGH);
    _pin = pin;
}

void PPMintIn::rising(){
    PPMintIn::latest_interrupted_pin = PCintPort::arduinoPin;
    PCintPort::attachInterrupt(latest_interrupted_pin, &rising, RISING);
    PPMintIn::pwm_value = micros()-PPMintIn::prev_time;
}

void PPMintIn::falling(){
    PPMintIn::latest_interrupted_pin=PCintPort::arduinoPin;
    PCintPort::attachInterrupt(latest_interrupted_pin, &rising, RISING);
    PPMintIn::pwm_value = micros()-PPMintIn::prev_time;
}

void PPMintIn::begin(){
    PCintPort::attachInterrupt(_pin, &rising, RISING);
}

void PPMintIn::getSignal(){
    return(PPMintIn::pwm_value);
}

Вот код .h

#ifndef PPMINTIN_H
#define PPMINTIN_H

#if defined(ARDUINO) && ARDUINO >= 100
  #include "Arduino.h"
  #else
  #include "WProgram.h"
#endif
#include "PinChangeInt.h"

class PPMintIn{
public:
    PPMintIn(int pin);
    void begin();
    void getSignal();
    int _pin;
    volatile int pwm_value;
    volatile int prev_time;
    uint8_t latest_interrupted_pin;
private:
    void rising();
    void falling();
};

#endif // PPMINTIN_H

вот полная версия на github, если я не указал ее здесь. https://github.com/tisaconundrum2/PPMintIn

, 👍1

Обсуждение

IDE, вероятно, не может проанализировать эти полные пути. Почему вы используете их вместо того, чтобы полагаться на то, что IDE знает, где находятся заголовки?, @Ignacio Vazquez-Abrams

потому что, когда я использую консоль отладки, включенную в IDE, она не может найти файлы. Только когда я делаю полные пути, он знает, чего я хочу, @tisaconundrum

Ищем заголовочный файл C:\Users\User\Documents\Arduino\RCRoomba_TestPulseV2\libraries\PinChangeInt\PinChangeInt.h Library.java 98 (<инициализация>): Ищем заголовочный файл:\Users\User\Documents\Arduino\RCRoomba_TestPulseV2\libraries\PPMintIn\PPMintIn.h он просто прокручивает это навсегда, @tisaconundrum

http://i.imgur.com/awwtHKj.png, @tisaconundrum

Нет, *компилятор* знает, чего вы хотите. *IDE* понятия не имеет, поэтому не включает библиотеки для компиляции и компоновки., @Ignacio Vazquez-Abrams

компилятор ссылается на библиотеку, однако эти библиотеки, с которыми он связан, пусты и не содержат ничего., @tisaconundrum

Я не уверен, что вы понимаете, что такое "связывание". Особенно с учетом того, что ошибки, опубликованные в верхней части этого вопроса, являются ошибками ссылок., @Ignacio Vazquez-Abrams

Ну хорошо, я сделал то, что вы предложили, вот результат http://i.imgur.com/W1gpqIh.png И когда я экспортирую обе библиотеки, чтобы посмотреть, что внутри, они в основном пустые новые библиотеки., @tisaconundrum

Теперь IDE поступает правильно. Однако в самой вашей библиотеке "PPMintIn" есть ошибки, которые необходимо исправить., @Ignacio Vazquez-Abrams

почему моя библиотека сидит с моим файлом INO, я думал, что он должен идти в папку библиотек., @tisaconundrum

Вам также необходимо следить за регистром заглавных букв — заголовочный файл Arduino — это Arduino.h, а не arduino.h, и ваш основной заголовочный файл (ppmintin.h) должен иметь тот же регистр, что и папка вашей библиотеки (PPMintIn.h). В операционных системах с файловыми системами, чувствительными к регистру, в противном случае он полностью сломается., @Majenko

Какую версию IDE вы используете и как вы создали библиотеку?, @Majenko

Так и должно быть до тех пор, пока среда IDE не создаст его. Затем он копирует все в один каталог и строит его там., @Ignacio Vazquez-Abrams

http://i.imgur.com/r0BSQD5.png, @tisaconundrum

Также вам следует взглянуть на это, оно расскажет вам, почему вы получаете некоторые из своих ошибок: http://arduinoprosto.ru/q/14480/pass-a-member-function-pointer-to-a- метод иностранного класса edb-lib, @Majenko

Я переделал весь свой код и удалил кучу копий одной и той же библиотеки. Во всяком случае, теперь я получаю меньше ошибок. Это должно быть хорошо, но я получаю эту ошибку http://i.imgur.com/ZIhuule.png, @tisaconundrum

что не имеет для меня смысла, потому что функция допускает целые числа PPMintIn::PPMintIn(int pin){ pinMode(pin, INPUT);\ цифровая запись (вывод, ВЫСОКИЙ); _пин = штифт; }, @tisaconundrum


1 ответ


Лучший ответ:

0

Как мы с Маженко пытались объяснить в разделе Передача указателя функции-члена на метод стороннего класса (EDB Lib), вы не можете передать функция-член класса, где ожидается статическая функция.


Ваша ошибка:

PCintPort::attachInterrupt(latest_interrupted_pin, &rising, RISING);

Ошибка:

/home/nick/sketchbook/libraries/PPMintIn/ppmintin.cpp: In member function ‘void PPMintIn::rising()’:
/home/nick/sketchbook/libraries/PPMintIn/ppmintin.cpp:22: error: ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function.  Say ‘&PPMintIn::rising’

PCintPort::attachInterrupt ожидает переменную PCIntvoidFuncPtr:

int8_t PCintPort::attachInterrupt(uint8_t arduinoPin, PCIntvoidFuncPtr userFunc, int mode)

То есть:

typedef void (*PCIntvoidFuncPtr)(void);

Это статическая функция (не функция класса).

Однако у вас есть это как функция класса:

class PPMintIn{
public:
    PPMintIn(int pin);
    void begin();
    void getSignal();
    int _pin;
    volatile int pwm_value;
    volatile int prev_time;
    uint8_t latest_interrupted_pin;
private:
    void rising();
    void falling();
};

Теперь вы можете сделать rising и falling статическими, но теперь они не могут получить доступ ни к одной из переменных класса (например, pwm_value, prev_time, last_interrupted_pin).

Все это нуждается в редизайне. Вы можете попробовать сделать PPMintIn пространством имен, а не классом.


Относительно одного из комментариев:

Сообщение об ошибке

Если ваш класс не реализует operator(), эта строка не имеет смысла:

chan1(15);

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

,