неопределенная ссылка на `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
@tisaconundrum, 👍1
Обсуждение1 ответ
Лучший ответ:
Как мы с Маженко пытались объяснить в разделе Передача указателя функции-члена на метод стороннего класса (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, чтобы найти скриншот какого-либо текста.
- Ошибка компиляции с использованием arduino-mk в Arch Linux (неопределенная ссылка на __dso_handle)
- Как подключить Wi-Fi Shield ESP-12E-ESP8266-UART-WIFI-Wireless-Shield к Arduino
- Ошибка компиляции кода для Arduino/Genuino Uno
- Экран LCD 16*02 I2C показывает только первый напечатанный символ
- Глобальные переменные занимают много места в динамической памяти.
- Будет ли .ino-скетч ардуино компилироваться непосредственно на GCC-AVR?
- Поддерживают ли чипы ATMega 328/2560 JTAG-программатор и аппаратный отладчик?
- Запуск С для ардуино
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