crash when construct UpdateMsg with name field

My sample code as follows:

{
emaaccess::UpdateMsg msg;
msg.name("hello");
fprintf(stderr, "process update msg with name:%s", msg.getName().c_str());
}


The app will crash when calling getName(), why ? I already called name() function to set this field.

Best Answer

  • Hi @iscas.wang

    A couple of things here.

    • you are trying to change the RIC name of an open stream - i.e. the RIC would have been set in the Refreshmsg, and then you are trying to change it in the UpdateMsg. To change the name of an existing item you would have to close the existing stream and send a new RefreshMsg with ClosedRedirectedEnum - to tell the consumer the item has been renamed, with the new Item name included in the RefreshMsg - so that the consumer can re-request using the new RIC name
    • Also, my understanding is that you cannot just decode a message that has just been encoded - although from your limited code snippet it would appear you have not yet completed encoding the message anyway.

    Please the following existing post for one way achieving this decode of just encoded object in EMA C++ - Forum | Refinitiv Developer Community I understand that you would have to complete encoding the message before you can decode it using the above technique,

Answers

  • @umer.nalla Thanks for your reply. I read the article you provided, It seems the decode only works for FieldList, not for UpdateMsg or RefreshMsg.

    I read the source code for UpdateMsg.cpp, it seems that Updatemsg::name() method stores the name value in MsgEncoder object pointer(which actually points to UpdateMsgEncoder) with following code:

    UpdateMsg& UpdateMsg::name( const EmaString& name )
    {
    if ( !_pEncoder )
    _pEncoder = g_pool._updateMsgEncoderPool.getItem();

    _pEncoder->name( name );
    return *this;
    }

    void UpdateMsgEncoder::name( const EmaString& value )
    {
    acquireEncIterator();

    #ifdef __EMA_COPY_ON_SET__
    _nameSet = true;
    _name = value;
    #else
    _pName = &value;
    #endif
    }


    But when calling getName(), it uses MsgDecoder object pointer which is unitialized with default NULL value. The application will crash on getName().

    const EmaString& Msg::getName() const
    {
    return _pDecoder->getName();
    }


    My usage scenary is simple. I just want to construct one UpdateMsg with field list payload and also its ric name. And later I want to extract the ric name for some usage. If I can't use UpdateMsg::name() field to store the ric name and use Msg::getName() to get the ric name again, Then I must construct another struct type with one filed storing the ric name and another UpdateMsg with field list payload.

  • Hi @wangfugen2015

    Unfortunately, the Encoder and Decoder are separate from each other and therefore I believe you will have to use your own struct etc to store the RIC name for later usage.

  • @umer.nalla OK, so constructing my own struct to store ric and UpdateMsg is the only current solution. By the way, may I know why Encoder & Decoder are seperate from each other ? For example, I constructed one UpdateMsg and call toString() to decode the message. (As I previously pointed on the link you provided, decode just encoded object worked on FieldList, but not on UpdateMsg). Many thanks.

  • testffffffffffffffffffffffffffffffff

  • In the other example, it is using a StaticDecoder where it is passing in the completed FieldList and the dictionary to decode the completed fieldlist.

  • Ok, I would follow the guide, then see it's to be resolve. Thanks umer