c++ - boost IPC Message_Queue try_receive 抛出 interprocess_exception::library_error

标签 c++ exception boost c++11 boost-interprocess

我正在使用 boost::interprocess::message_queue 在我的两个进程之间进行进程间通信。

这是我第一次使用它,所以我不清楚这个异常,因为我找不到任何关于它的文档。

我的类(class)设置如下:

struct Pos{float X,Y,Z;};
struct Quat{float W,X,Y,Z;};
typedef unsigned char Byte;
struct NPCDataFoot
{
    //some Pos and Quat variables here too
    unsigned short AnimationIndex;
    void Apply(NPCDataFoot &data){AnimationIndex=data.AnimationIndex;}
    NPCDataFoot(){AnimationIndex=0;}
};
struct NPCDataVehicle
{
    //many many more
    unsigned short lrAnalog;
    void Apply(NPCDataVehicle &data){lrAnalog=data.lrAnalog;}
    NPCDataVehicle(){lrAnalog = 0;}
};
enum TransmissionDataType{
    TDT_NewNPC,//many more...
};
const unsigned short QueueMaxSize = 256;
struct ExchangeData
{
    unsigned short  CommandType;
    unsigned short  NPCPlayerID;
    Byte            State;
    NPCDataFoot     OnFootData;
    NPCDataVehicle  InCarData;
    float MoveSpeed;
    Pos MoveToPos;
    //206
    ExchangeData(unsigned short CommandType = 0, unsigned short NPCPlayerid = 0xFFFF)
        : CommandType(CommandType), NPCPlayerID(NPCPlayerid)
    {}
    ExchangeData(unsigned short CommandType, unsigned short NPCPlayerid, NPCDataFoot& foot_data, NPCDataVehicle& car_data)
        : CommandType(CommandType), NPCPlayerID(NPCPlayerid), OnFootData(foot_data), InCarData(car_data)
    {}
};

我的两个程序都设置为使用/zp1 标志进行编译(将结构/类对齐到 1 字节对齐)。

现在每当我到达这段代码时:

ServerMsgQueue * message_queue = NULL;
PLUGIN_EXPORT void PLUGIN_CALL
    ProcessTick()
{
    static bool init = false;
    static ExchangeData DataTransmision;
    if(!init)
    {
        try
        {
            ServerMsgQueue = new message_queue(open_or_create              
                    ,string_format("REMOTESHAREDMEMORYBTWNPRCS%04x",GetServerVarAsInt("port")).c_str()
                    ,1024 * QueueMaxSize,sizeof(ExchangeData)); 
        }
        catch(interprocess_exception &ex)
        {
            std::cout << ex.what() << ":" << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << std::endl;
        }
        init = true;
    }
    static unsigned int unused;
    if(ServerMsgQueue)
    {
        try
        {
            if(ServerMsgQueue->try_receive(&DataTransmision,sizeof(ExchangeData),unused,unused))
            {
                switch(DataTransmision.CommandType)
                {//some cases
                default:{std::cout << "UNKNOWN RECEIVED DATA!!!" << std::endl;break;}
                }
            }
        }
        catch(interprocess_exception &ex)
        {
            //this happens always
            std::cout << ex.what() << ":" << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << std::endl;
        }
    }
}

应用程序在使用 try_receive 的 block 中不断发出“boost::interprocess_exception::library_error”。

在这种情况下我做错了什么?我确定发送的数据大小相同,因为 1) 我使用相同的 header ,并且 2) 我使用相同的选项进行编译。

我已确认两个程序中的变量大小与以下代码相同:

MessageBox(NULL,string_format(
"Pos(%d):Quat(%d):NPCDataFoot(%d):NPCDataVehicle(‌​%d):ExchangeData(%d)",
sizeof(Pos),sizeof(Quat),sizeof(NPCDataFoot),sizeof(NPCData‌Vehicle),sizeof(ExchangeData)).c_str()
,"Reported sizes Client",0);

编辑:我似乎已经神奇地“解决”了它;

似乎这段代码是错误的:

static unsigned int unused;
if(ServerMsgQueue->try_receive(&DataTransmision,sizeof(ExchangeData),unused,unused))

改成

unsigned int Priority;
size_t sizexxx;
if(ServerMsgQueue->try_receive(&DataTransmision,sizeof(ExchangeData),sizexxx,Priority))

有人可以解释为什么这个行得通而其他代码行不通吗?

最佳答案

查看 message_queue::do_receive 的源代码(从 message_queue::try_receive 调用); do_receive 首先将消息大小写入“out”参数 recvd_size(代码中对 unused 的引用),然后将优先级写入“out”参数 priority(也是对代码中unused 的引用——因此有效地覆盖了 recvd_size 优先级 值)。紧接着,对 memcpy 的调用使用现在不正确的 recvd_size,导致您观察到的行为(不完整的复制或缓冲区溢出,取决于 priority ).

可以说,库的作者应该为 memcpy< 使用原始的 top_msg->len(而不是“out”参数 recvd_size)/ 字节数。但是,为了避免这些意外,请始终对“输出”参数使用不同的变量(如果您愿意,可以将它们称为 unused1unused2)。

关于c++ - boost IPC Message_Queue try_receive 抛出 interprocess_exception::library_error,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17900777/

相关文章:

c++ - 在 linux 中使用 QXmlDefaultHandler 编译错误 c++

JAVA。我收到 'unreported exception' 编译器错误

C++/boost : use tuple ctors when subclassing

boost - 配置找不到库的版本

c++ - boost 变体 : how to get currently held type?

尽管使用指针将其初始化为一维,但 C++ 仍将数组用作多维

c++ - 在静态库中硬编码的代码文件和头文件路径?

php - 我正在阅读 RSS 链接,如果它无效然后抛出异常,如何使用 PHP 处理它

c++ - Qt std::runtime_error 等效项

c++ - 为新的 ArrayFire 版本调整 MatchedFilter 算法时出现问题