简体   繁体   English

Boost IPC Message_Queue try_receive引发interprocess_exception :: library_error

[英]Boost IPC Message_Queue try_receive throws interprocess_exception::library_error

I am making interprocess communication between two of my processes with boost::interprocess::message_queue. 我正在使用boost :: interprocess :: message_queue在两个进程之间进行进程间通信。

This is the first time I'm using it so this exception isn't clear to me because I cannot find any documentation on it. 这是我第一次使用它,因此我看不到该异常,因为我找不到关于它的任何文档。

I have my classes setup as following: 我的班级设置如下:

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)
    {}
};

both my programs are set to compile with the /zp1 flag (Align structures/classes to 1-byte alignment). 我的两个程序都设置为使用/ zp1标志进行编译(将结构/类对齐为1字节对齐)。

now whenever I reach this code: 现在,只要我到达此代码:

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;
        }
    }
}

The application keeps issuing "boost::interprocess_exception::library_error" in the block where try_receive is being used. 应用程序在使用try_receive的块中不断发出“ boost :: interprocess_exception :: library_error”。

What am I doing wrong in this case? 我在这种情况下做错了什么? I'm sure the data send is the same size because 1) i use the same header and 2) I compile with the same options. 我确定数据发送的大小是相同的,因为1)我使用相同的标头,并且2)我使用相同的选项进行编译。

I have confirmed that the variable sizes are the same with the following code in both programs: 我已经确认两个程序中的变量大小与以下代码相同:

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);

Edit: I seem have "solved" it.. magicly; 编辑:我似乎已经“解决”了它。

It seems that this code was the error: 似乎此代码是错误:

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

changed it to 改成

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

Can someone explain why this works and the other code not? 有人可以解释为什么这行得通,而其他代码行不通吗?

This is most likely caused by your use of /zp1 . 这很可能是由于您使用/zp1引起的。 Your program and the libraries to which it links will think that structures have different sizes and/or member locations. 您的程序及其链接到的库将认为结构具有不同的大小和/或成员位置。 Don't do that. 不要那样做

See the source code for message_queue::do_receive (called from message_queue::try_receive ); 参见message_queue::do_receive的源代码(从message_queue::try_receive ); do_receive first writes the message size to the "out" parameter recvd_size (a reference to unused in your code), then writes the priority to the "out" parameter priority ( also a reference to unused in your code -- thus effectively overwriting recvd_size with the priority value). do_receive首先将消息大小写入“ out”参数recvd_size (对代码中unused的引用),然后将优先级写入“ out”参数priority对代码中unused的引用),从而有效地覆盖了recvd_size priority值)。 Immediately below, the call to memcpy uses the now incorrect recvd_size , leading to the behaviour you observed (incomplete copy or buffer overrun, depending on priority ). 在紧下方,对memcpy的调用使用了现在不正确的recvd_size ,从而导致您观察到的行为(不完整的副本或缓冲区溢出,具体取决于priority )。

Arguably, the author of the library should have used the original top_msg->len (instead of the "out" parameter recvd_size ) for the memcpy bytecount. 可以说,该库的作者应该对memcpy字节计数使用原始的top_msg->len (而不是“ out”参数recvd_size )。 However, in order to avoid these kinds of surprises, always use distinct variables for "out" parameters (call them unused1 and unused2 if you so desire). 但是,为了避免此类意外,请始终对“输出”参数使用不同的变量(如果需要,可以将它们unused1unused1和“ unused2 )。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 尝试使用 boost::interprocess::message_queue 时出现 library_error 异常 - getting library_error exception when trying to use boost::interprocess::message_queue boost::interprocess_exception - 创建 shared_memory_object 时的 library_error 异常 - boost::interprocess_exception - library_error exception when creating shared_memory_object 错误:“ size_type”不是“ boost :: interprocess :: message_queue”的成员 - error: ‘size_type’ is not a member of ‘boost::interprocess::message_queue’ boost interprocess message_queue和fork - boost interprocess message_queue and fork boost :: interprocess :: message_queue权限被拒绝 - boost::interprocess::message_queue permission denied boost::interprocess::message_queue 在第二个进程中没有收到消息 - boost::interprocess::message_queue no message received in second process boost :: interprocess message_queue-Windows 7低完整性进程 - boost::interprocess message_queue - Windows 7 low integrity process 使用boost :: interprocess :: message_queue多个应用程序安全吗? - Is it safe to consume a boost::interprocess::message_queue multiple applications? boost::interprocess message_queue 性能 - 相当慢? - boost::interprocess message_queue performance - rather slow? 如何解决 Boost 错误:在抛出 'boost::interprocess::interprocess_exception' 的实例后调用终止 - How to solve Boost Error: terminate called after throwing an instance of 'boost::interprocess::interprocess_exception'
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM