不能将变量"pdu"声明为抽象类型"Tins::pdu"



我使用libtins捕获数据包,并使用moodycamel并发队列对捕获的数据包进行排队。

我注意到出列操作失败,因为PDU是一种抽象类型。

因此无法编译,

error: cannot declare variable ‘pdu’ to be of abstract type ‘Tins::PDU’

我不确定在这个阶段该怎么做来修复这个错误。

我尝试过指针路由,但它没有编译太

Tins::PDU *pdu;
if(PacketQueue.try_dequeue(pdu) == false) {
continue;
}

错误,

error: cannot convert ‘std::remove_reference<Tins::PDU&>::type {aka Tins::PDU}’ to ‘Tins::PDU*’ in assignment
element = std::move(el); // NOLINT
~~~~~~~~^~~~~~~~~~~~~~~

代码

moodycamel::ConcurrentQueue<PDU> PacketQueue;
void worker()
{
while(true) {
Tins::PDU pdu;
if(PacketQueue.try_dequeue(pdu) == false) {
continue;
}

// Do Work
}
}
bool callback(PDU &pdu)
{
PacketQueue.enqueue(pdu);
return true;
}
moodycamel::ConcurrentQueue<PDU> PacketQueue;
...
bool callback(PDU &pdu)
{
PacketQueue.enqueue(pdu);

这无法正常工作。

您收到了对某个具体对象的基类的引用。按值排队会导致对象切片——您只是复制基类子对象并丢弃所有派生类状态(和类型信息(。

编译器阻止您对这种抽象类型进行出队列,这是一个方便的巧合,因为否则您必须弄清楚为什么成功的入队/出队列会产生垃圾PDU。

我已经尝试了指针路由。。。

嗯,你需要某种间接方式。您还没有显示您尝试的代码,但我认为您忘记更改队列的类型以匹配。

如果你想打开/取消队列指针,你需要:

  1. 将队列更改为指针队列
  2. 克隆(多态深度复制(要排队的对象(假设您获得其引用的对象在回调返回后将被清理(
  3. 请记住,您现在负责在将克隆的pdu出列后销毁它(或者,更好的做法是,首先使用unique_ptr(

正确的解决方案可能看起来像这样(完全未经测试(示例:

// title case is conventionally used for types, not variables
// (of course, it would also be better to avoid globals ...)
moodycamel::ConcurrentQueue<std::unique_ptr<PDU>> packetQueue;
void worker()
{
while(true) {
std::unique_ptr<PDU> pdu;
if(packetQueue.try_dequeue(pdu) == false) {
continue;
}
// Do Work on *pdu
}
}
bool callback(PDU &pdu)
{
packetQueue.enqueue(std::unique_ptr<Tins::PDU>(pdu.clone()));
return true;
}

最新更新