#c #qt #reference
#c #qt #ссылка
Вопрос:
Я работал с исходным кодом нового проекта на GitHub, чтобы я мог лучше познакомиться с работой в команде людей на языке c . я понимаю, что неопределенная ошибка ссылки — это объявление функции или переменной внутри другого класса без предварительной инициализации этого класса, но эта ошибка кажетсячтобы быть чем-то противоположным, пример вывода выглядит следующим образом
undefined reference to `PxtoneUnitIODevice::PxtoneUnitIODevice(QObject*, pxtnService const*, mooParams const*)'
/usr/bin/ld: /home/prinzeono/Desktop/Projects/ptcollabProject/build-ptcollab-Desktop_Qt_5_15_2_GCC_64bit-Debug/src/../../ptcollab/src/editor/audio/NotePreview.cpp:92: undefined reference to `PxtoneUnitIODevice::addUnit(pxtnUnitTone*)'
/usr/bin/ld: /home/prinzeono/Desktop/Projects/ptcollabProject/build-ptcollab-Desktop_Qt_5_15_2_GCC_64bit-Debug/src/../../ptcollab/src/editor/audio/NotePreview.cpp:95: undefined reference to `PxtoneUnitIODevice::addUnit(pxtnUnitTone*)'
/usr/bin/ld: NotePreview.o: in function `NotePreview::~NotePreview()':
Код в NotePreview.cpp заключается в следующем
#include "NotePreview.h"
#include <QAudioFormat>
#include <QAudioOutput>
#include <QDebug>
#include <QSettings>
#include "AudioFormat.h"
#include "NotePreview.h"
#include "PxtoneUnitIODevice.h"
#include "editor/Settings.h"
// TODO: m_unit should probably be not a member variable but an r-value passed
// to the child.
constexpr int32_t LONG_ON_VALUE = 100000000;
static PxtoneUnitIODevice *device = nullptr;
static QAudioOutput *audio = nullptr;
NotePreview::NotePreview(const pxtnService *pxtn, const mooParams *moo_params,
int unit_no, int clock,
std::list<EVERECORD> additional_events, int duration,
std::shared_ptr<const pxtnWoice> starting_woice,
int bufferSize, QObject *parent)
: QObject(parent),
m_pxtn(pxtn),
m_unit(nullptr),
m_moo_state(nullptr),
m_moo_params(moo_params) {
if (!ChordPreview::get() || unit_no == -1) {
m_unit = std::make_unique<pxtnUnitTone>(starting_woice);
m_this_unit = m_unit.get();
moo_params->resetVoiceOn(m_this_unit);
if (unit_no != -1)
for (const EVERECORD *e = m_pxtn->evels->get_Records();
e amp;amp; e->clock <= clock; e = e->next) {
if (e->unit_no == unit_no) {
moo_params->processEvent(m_this_unit, e, clock, -1, m_pxtn);
}
}
} else {
m_moo_state = std::make_unique<mooState>();
pxtnVOMITPREPARATION prep{};
prep.flags |= pxtnVOMITPREPFLAG_loop | pxtnVOMITPREPFLAG_unit_mute;
prep.start_pos_sample = clock * 60 * 44100 /
m_pxtn->master->get_beat_clock() /
m_pxtn->master->get_beat_tempo();
prep.master_volume = moo_params->master_vol;
pxtn->moo_preparation(amp;prep, *m_moo_state);
for (const EVERECORD *e = m_pxtn->evels->get_Records();
e amp;amp; e->clock <= clock; e = e->next) {
if (e->unit_no < m_moo_state->units.size())
moo_params->processEvent(amp;m_moo_state->units.at(e->unit_no), e, clock,
-1, m_pxtn);
}
m_this_unit = amp;m_moo_state->units.at(unit_no);
}
for (const EVERECORD amp;e : additional_events)
moo_params->processEvent(m_this_unit, amp;e, clock, -1, pxtn);
m_this_unit->Tone_KeyOn();
// We don't constantly reset because sometimes the audio engine forces
// [life_count = 0] (say at the end of the sample)
if (m_unit != nullptr) {
std::shared_ptr<const pxtnWoice> woice = m_this_unit->get_woice();
for (int i = 0; i < woice->get_voice_num(); i) {
// TODO: calculating the life count should be more automatic.
auto tone = m_this_unit->get_tone(i);
tone->on_count = duration;
tone->life_count = duration woice->get_instance(i)->env_release;
}
}
if (m_moo_state != nullptr) {
for (auto amp;unit : m_moo_state->units) {
pxtnUnitTone *u = amp;unit;
std::shared_ptr<const pxtnWoice> woice = u->get_woice();
for (int i = 0; i < woice->get_voice_num(); i) {
auto tone = u->get_tone(i);
if (u == m_this_unit || tone->on_count > 0) {
tone->on_count = duration;
tone->life_count = duration woice->get_instance(i)->env_release;
}
}
}
}
if (device == nullptr) {
/*Error Here*/device = new PxtoneUnitIODevice(nullptr, m_pxtn, moo_params);
device->open(QIODevice::ReadOnly);
}
if (m_unit != nullptr) m_unit_ids.push_back(device->addUnit(m_unit.get()));
if (m_moo_state != nullptr) {
for (auto amp;unit : m_moo_state->units)
m_unit_ids.push_back(device->addUnit(amp;unit));
}
if (audio == nullptr) {
audio = new QAudioOutput(pxtoneAudioFormat(), device);
audio->setVolume(1.0);
audio->setBufferSize(bufferSize);
audio->start(device);
}
}
void NotePreview::processEvent(EVENTKIND kind, int32_t value) {
m_moo_params->processNonOnEvent(m_this_unit, kind, value, m_pxtn);
}
static EVERECORD ev(int32_t clock, EVENTKIND kind, int32_t value) {
EVERECORD e;
e.clock = clock;
e.kind = kind;
e.value = value;
return e;
}
NotePreview::NotePreview(const pxtnService *pxtn, const mooParams *moo_params,
int unit_no, int clock, int pitch, int vel,
int bufferSize, QObject *parent)
: NotePreview(
pxtn, moo_params, unit_no, clock,
{ev(clock, EVENTKIND_KEY, pitch), ev(clock, EVENTKIND_VELOCITY, vel)},
LONG_ON_VALUE, pxtn->Woice_Get(EVENTDEFAULT_VOICENO), bufferSize,
parent) {}
NotePreview::NotePreview(const pxtnService *pxtn, const mooParams *moo_params,
int unit_no, int clock, int duration,
std::list<EVERECORD> additional_events, int bufferSize,
QObject *parent)
: NotePreview(pxtn, moo_params, unit_no, clock, additional_events, duration,
pxtn->Woice_Get(EVENTDEFAULT_VOICENO), bufferSize, parent){};
NotePreview::NotePreview(const pxtnService *pxtn, const mooParams *moo_params,
int unit_no, int clock,
std::list<EVERECORD> additional_events, int bufferSize,
QObject *parent)
: NotePreview(pxtn, moo_params, unit_no, clock, LONG_ON_VALUE,
additional_events, bufferSize, parent){};
NotePreview::NotePreview(const pxtnService *pxtn, const mooParams *moo_params,
int pitch, int vel, int duration,
std::shared_ptr<const pxtnWoice> woice, int bufferSize,
QObject *parent)
: NotePreview(pxtn, moo_params, -1, 0,
{ev(0, EVENTKIND_KEY, pitch), ev(0, EVENTKIND_VELOCITY, vel)},
duration, woice, bufferSize, parent) {}
NotePreview::~NotePreview() {
/*Error Here*/for (const auto amp;id : m_unit_ids) device->removeUnit(id);
}
Код в PxtoneUnitIODevice.h выглядит следующим образом
#ifndef PXTONEUNITIODEVICE_H
#define PXTONEUNITIODEVICE_H
#include <QIODevice>
#include <map>
#include "pxtone/pxtnService.h"
#include "pxtone/pxtnWoice.h"
/* An IO device for playing audio from a number of custom units separately from
* the moo stream. It's not just a single unit because multiplexing and having
* one audio output continuously playing is significantly faster on Windows.
*/
class PxtoneUnitIODevice : public QIODevice {
Q_OBJECT
public:
PxtoneUnitIODevice(QObject *parent, const pxtnService *pxtn,
const mooParams *moo_params);
void removeUnit(int unit_id);
int addUnit(pxtnUnitTone *unit);
virtual ~PxtoneUnitIODevice() { close(); };
signals:
void MooError();
private:
std::map<int, pxtnUnitTone *> m_units;
const pxtnService *m_pxtn;
const mooParams *m_moo_params;
int m_next_unit_id;
qint64 readData(char *data, qint64 maxlen);
qint64 writeData(const char *data, qint64 len);
};
#endif // PXTONEUNITIODEVICE_H
Я хотел бы знать, почему я получаю эту ошибку и, возможно, как ее исправить
Комментарии:
1. Ну, вы показываете, где
PxtoneUnitIODevice
объявлены конструктор иaddUnit
. Они действительно где-то реализованы? Это недостающая реализация, на которую жалуется компоновщик.2. @IgorTandetnik Да, это реализовано
3. Ну, компоновщик считает иначе.
Ответ №1:
Просто нужно было сказать QT использовать последнюю версию, проблема решена