我想设置一个 QueueHandler 来组织任意类的函数调用。就我而言,我有一个不应过载的 UDP 接口。因此,我有一个函数调用队列,以便每 N 毫秒(或秒)发送一次 UDP 请求。当尝试将函数添加到队列时,我收到 LNK2019 错误,指出存在未解析的外部符号(据我了解此错误,这意味着存在已声明的符号,但未定义)。 不过,为了说明问题,我将其分解为重现错误的基本原理:
队列处理程序
/* =============== Header file QueueHandler.h ============================= */
#pragma once
#include <QThread>
#include <queue>
#include <functional>
#include <iostream>
#include <chrono>
class QueueHandler : public QThread
{
Q_OBJECT
public:
QueueHandler(QObject* parent=nullptr);
~QueueHandler() = default;
void run() override;
template<typename _Callable, typename... Args>
void QueueFunction(_Callable&& __f, Args&&... args);
private:
uint m_iSleepSec{ 2 };
std::queue<std::function<void()>> funcs;
};
/* =============== implementation QueueHandler.cpp ============================= */
//#include "QueueHandler.h"
QueueHandler::QueueHandler(QObject* parent /*= nullptr*/)
{}
void QueueHandler::run()
{
bool bRunning = true;
while (bRunning)
{
if (!funcs.empty())
{
std::function<void()> func = funcs.front();
funcs.pop();
func();
}
else
{
std::cout << "No command available.\n";
}
std::cout << "Sleep for " << m_iSleepSec << "seconds...";
this->msleep(m_iSleepSec * 1000);
std::cout << "... proceed processing. \n ";
}
}
template<typename _Callable, typename... Args>
void QueueHandler::QueueFunction(_Callable&& __f, Args&&... args)
{
std::function<void()> func = std::bind(std::forward<_Callable>(__f), std::forward<Args>(args)...);
funcs.push(func);
}
填充队列的测试类:
/* Header file LpTest.h*/
/* =============== implementation LpTest.cpp ============================= */
#pragma once
#include "QueueHandler.h"
#include <QtCore>
#include <memory>
class LpTest : public QObject
{
Q_OBJECT
public:
LpTest();
~LpTest() = default;
void fillQueue();
void testFunction(int iIn);
void ping();
signals:
void resultReady(QVariant var);
private:
std::unique_ptr<QueueHandler> m_pQueueHandler{};
};
/* =============== implementation LpTest.cpp ============================= */
//#include "LpTest.h"
LpTest::LpTest()
{
m_pQueueHandler = std::make_unique<QueueHandler>(this);
}
void LpTest::fillQueue()
{
m_pQueueHandler->QueueFunction(&LpTest::testFunction, 2);
}
void LpTest::testFunction(int iIn)
{
std::cout << "testFunction: " << iIn << "\n";
}
void LpTest::ping()
{
std::cout << "ping\n";
}
Main.cpp 看起来就像:
#include <QtCore/QCoreApplication>
#include "LpTest.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
LpTest myLp{};
myLp.fillQueue();
return a.exec();
}
从 LpTest 类调用
fillQueue()
时会发生错误。
顺便说一句,当队列在 LpTest 类中定义时,一切正常。但我想将其放入另一个类中,因此稍后我可能会重用 QueueHandler。
确切的错误是:
error LNK2019: unresolved external symbol "public: void __cdecl QueueHandler::QueueFunction<void (__cdecl QueueHandler::*)(class QString),char const (&)[6]>(void (__cdecl QueueHandler::*&&)(class QString),char const (&)[6])" (??$QueueFunction@P8QueueHandler@@EAAXVQString@@@ZAEAY05$$CBD@QueueHandler@@QEAAX$$QEAP80@EAAXVQString@@@ZAEAY05$$CBD@Z) referenced in function "public: void __cdecl LpTest::fillQueue(void)" (?fillQueue@LpTest@@QEAAXXZ)
提前致谢!
我已经红色了 Microsoft 的 LNK2019 错误指南,但无法将其应用于我的问题,因为我认为一切都已定义在它应该在的位置。 Microsoft 链接器工具错误 LNK2019
问题解决了。不允许在cpp文件中定义模板函数。我已将 QueueFunction(_Callable&& __f, Args&&... args) 的定义移至头文件中(丑陋,但这似乎是要走的路...)