簡體   English   中英

Boost IPC Message_Queue try_receive引發interprocess_exception :: library_error

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

我正在使用boost :: interprocess :: message_queue在兩個進程之間進行進程間通信。

這是我第一次使用它,因此我看不到該異常,因為我找不到關於它的任何文檔。

我的班級設置如下:

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的塊中不斷發出“ boost :: interprocess_exception :: library_error”。

我在這種情況下做錯了什么? 我確定數據發送的大小是相同的,因為1)我使用相同的標頭,並且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))

有人可以解釋為什么這行得通,而其他代碼行不通嗎?

這很可能是由於您使用/zp1引起的。 您的程序及其鏈接到的庫將認為結構具有不同的大小和/或成員位置。 不要那樣做

參見message_queue::do_receive的源代碼(從message_queue::try_receive ); do_receive首先將消息大小寫入“ out”參數recvd_size (對代碼中unused的引用),然后將優先級寫入“ out”參數priority對代碼中unused的引用),從而有效地覆蓋了recvd_size priority值)。 在緊下方,對memcpy的調用使用了現在不正確的recvd_size ,從而導致您觀察到的行為(不完整的副本或緩沖區溢出,具體取決於priority )。

可以說,該庫的作者應該對memcpy字節計數使用原始的top_msg->len (而不是“ out”參數recvd_size )。 但是,為了避免此類意外,請始終對“輸出”參數使用不同的變量(如果需要,可以將它們unused1unused1和“ unused2 )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM