You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OMNeT++ 6.0.1中opp_msgc生成代码编译错误求助

OMNeT++ 6.0.1 移植SIMCAN模拟器编译错误解决

问题描述

将SIMCAN模拟器从OMNeT++ 6.0预发布版11移植至OMNeT++ 6.0.1 + INET 4.4版本时,opp_msgc工具自动生成的SimcanPacket类代码出现编译错误,核心问题是调用omnetpp::fromAnyPtr<SimcanMsg>时触发**"调用已删除函数"**的报错。

相关代码与错误信息

1. SimcanPacket.msg定义

cplusplus {{
    #include "Base/Messages/SimcanMsg.h"
}}

import inet.common.INETDefs;
import inet.common.packet.chunk.Chunk;
import SimcanMsg;

//
// Simcan packet to send data through sockets
//
class SimcanPacket extends inet::FieldsChunk{
    
    @customize(true);
    SimcanMsg *msg;
}

2. SimcanPacket类实现

#ifndef _SIMCAN_PACKET_H_
#define _SIMCAN_PACKET_H_

#include "SimcanPacket_m.h"


/**
 * @class SimcanPacket SimcanPacket.h "SimcanPacket.h"
 *
 * Class that represents a Simcan Packet tos send message through TCP sockets
 *
 */
class SimcanPacket: public SimcanPacket_Base{


    public:

       /**
        * Destructor.
        */
        virtual ~SimcanPacket();


       /**
        * Constructor
        */
        SimcanPacket();

        virtual SimcanPacket_Base *dup() const;
};

#endif

3. 报错的生成代码片段(SimcanPacket_m.cc)

void SimcanPacketDescriptor::setFieldValue(omnetpp::any_ptr object, int field, int i, const omnetpp::cValue& value) const
{
    omnetpp::cClassDescriptor *base = getBaseClassDescriptor();
    if (base) {
        if (field < base->getFieldCount()){
            base->setFieldValue(object, field, i, value);
            return;
        }
        field -= base->getFieldCount();
    }
    SimcanPacket_Base *pp = omnetpp::fromAnyPtr<SimcanPacket_Base>(object); (void)pp;
    switch (field) {
        case FIELD_msg: pp->setMsg(omnetpp::fromAnyPtr<SimcanMsg>(value.pointerValue())); break; // ERROR HERE!!!
        default: throw omnetpp::cRuntimeError("Cannot set field %d of class 'SimcanPacket_Base'", field);
    }
}

4. 生成的SimcanPacket_m.h代码

namespace omnetpp {

template<> inline SimcanPacket_Base *fromAnyPtr(any_ptr ptr) { return check_and_cast<SimcanPacket_Base*>(ptr.get<cObject>()); }

}  // namespace omnetpp

5. 编译错误信息

src/Base/Messages/SimcanPacket_m.cc
src/Base/Messages/SimcanPacket_m.cc:457:36: error: call to deleted function 'fromAnyPtr'
        case FIELD_msg: pp->setMsg(omnetpp::fromAnyPtr<SimcanMsg>(value.pointerValue())); break;
                                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/alberto/omnetpp-6.0.1/include/omnetpp/any_ptr.h:111:4: note: candidate function [with T = SimcanMsg] has been explicitly deleted
T *fromAnyPtr(any_ptr object) = delete; // =delete prevents undeclared specializations
   ^
src/Base/Messages/SimcanPacket_m.cc:503:36: error: call to deleted function 'fromAnyPtr'
        case FIELD_msg: pp->setMsg(omnetpp::fromAnyPtr<SimcanMsg>(ptr)); break;
                                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/alberto/omnetpp-6.0.1/include/omnetpp/any_ptr.h:111:4: note: candidate function [with T = SimcanMsg] has been explicitly deleted
T *fromAnyPtr(any_ptr object) = delete; // =delete prevents undeclared specializations
   ^
2 errors generated.
make: *** [Makefile:187: out/clang-release//src/Base/Messages/SimcanPacket_m.o] Error 1

6. any_ptr.h相关代码

template<typename T>
T *fromAnyPtr(any_ptr object) = delete; // =delete prevents undeclared specializations

问题原因

OMNeT++ 6.0.1引入了any_ptr机制,默认删除了通用的fromAnyPtr模板,仅允许存在显式特化的版本。而SimcanMsg类未生成对应的fromAnyPtr特化模板,导致编译时匹配到了被删除的通用模板。OMNeT++ 6.0预发布版11尚未引入该机制,因此无此问题。

解决方法

方法1:为SimcanMsg添加fromAnyPtr特化模板

如果SimcanMsg是手动实现的cObject子类,在其头文件(SimcanMsg.h)末尾添加以下代码:

namespace omnetpp {
template<> inline SimcanMsg *fromAnyPtr(any_ptr ptr) {
    return check_and_cast<SimcanMsg*>(ptr.get<cObject>());
}
} // namespace omnetpp

如果SimcanMsg是通过.msg文件生成的,确保其.msg文件被正确编译,opp_msgc会自动为它生成对应的fromAnyPtr特化模板。

方法2:修改生成代码(临时方案,不推荐)

直接修改SimcanPacket_m.cc中的报错行,将omnetpp::fromAnyPtr<SimcanMsg>替换为check_and_cast<SimcanMsg*>,例如:

// 原代码
pp->setMsg(omnetpp::fromAnyPtr<SimcanMsg>(value.pointerValue()));
// 修改后
pp->setMsg(check_and_cast<SimcanMsg*>(value.pointerValue().get<cObject>()));

注意:此方法会在opp_msgc重新生成代码时被覆盖,仅作为临时调试使用。

方法3:检查.msg文件注解

确保SimcanPacket.msg中对SimcanMsg的引用正确,若SimcanMsg是cOwnedObject子类,可尝试添加@owned(true)注解(根据实际内存管理需求调整):

class SimcanPacket extends inet::FieldsChunk{
    @customize(true);
    @owned(true); // 若需要自动管理内存
    SimcanMsg *msg;
}

内容的提问来源于stack exchange,提问作者Alberto Núñez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 11:13:24