Thread: struct initialization / memcpy / pointer to memory

  1. #1
    Registered User
    Join Date
    Nov 2016
    Posts
    84

    struct initialization / memcpy / pointer to memory

    Hi,
    I want to initialize a struct using a constructor, fill in the variables using memcpy with values from msgDescriptor and create a pointer to the beginning of the memory adress for this struct (sorry I am not native speaker)
    But it doesn' t work.. Could someone tell me what I am doing wrong?

    HyqcmqprHandler.cpp
    Code:
    void
    TestHandler::callMsgTransmit(
        char * reqQName, 
        IMQMsg * msg, 
        bool reliably)
        throw(EBBaseExcept)
    {
        if (reliably)
        {
            try
            {
    
    
                if ((BASTrx::Current::getSingleton())->get_status() !=
                    BASTrx::Status::StatusActive)
                {
                    throw BASTrxRequiredExcept(MQ_TRC_GRP,
                                _callMsgTransmitFctName,
                                _callMsgTransmitFctName,
                                _FILE_, _LINE_);
                }
            }
            catch(...)
            {
                throw BASTrxRequiredExcept(MQ_TRC_GRP,
                        _callMsgTransmitFctName,
                        _callMsgTransmitFctName,
                        _FILE_, _LINE_);
            }
        }
    
    
        MQMD1 & msgDescriptor = msg->msgDescriptor(); 
        MQPMOputMsgOptions = { MQPMO_DEFAULT }; 
        putMsgOptions.Options = defaultPutOptions;
        if ( ! reliably)
        {
            (putMsgOptions.Options) &= ~MQPMO_SYNCPOINT;
            (putMsgOptions.Options) |= MQPMO_NO_SYNCPOINT;
        }
    
    
        const BASBuffer & buffer = msg->buffer(); 
        const char * data = buffer.getBuffer(); 
        MQLONG dataLength = buffer.tell();
        if ((0 == data) || (dataLength < 1))
        {
            throw EBinvParValExcept(MQ_TRC_GRP,
                    _callMsgTransmitFctName,
                    "msg->buffer()", 0, 0,
                    "(0 == (msg->buffer()).getBuffer()) ||"
                    " ((msg->buffer()).tell() < 1",
                    _FILE_, _LINE_);
        }
    
    
        //---------------------------------------------------------
        // struct 'TestHandler::TestParms'
        //---------------------------------------------------------
        const char validEyeCatcher[8] = { 'H', 'Y', 'Q', 'C', 'M', 'Q', 'P', 'R' };
    
    
        const char version_1_0[4] = { '0' , '1', '0', '0' };
    
    
    
    
        TestParms MsgParms;
    
    
        memcpy(MsgParms.m_eyeCatcher, validEyeCatcher, sizeof(MsgParms.m_eyeCatcher));
    
    
        memcpy(MsgParms.m_version, version_1_0, sizeof(MsgParms.m_version));
    
    
        memcpy(MsgParms.m_mqprQueueMgr, &msgDescriptor.ReplyToQMgr, sizeof(MsgParms.m_mqprQueueMgr));
    
    
        memcpy(MsgParms.m_mqprQueue, &reqQName, sizeof(MsgParms.m_mqprQueue));
    
    
        memcpy(MsgParms.m_mqprReplyQueue, &msgDescriptor.ReplyToQ, sizeof(MsgParms.m_mqprReplyQueue));
     
        memcpy(MsgParms.m_mqprMessageP, &data, sizeof(MsgParms.m_mqprMessageP));
    
    
        memcpy(MsgParms.m_mqprMessageL, &dataLength, sizeof(MsgParms.m_mqprMessageL));
    
    
        memcpy(MsgParms.m_mqprMessageId, &msgDescriptor.MsgId, sizeof(MsgParms.m_mqprMessageId));
    
    
        memcpy(MsgParms.m_mqprCorrelId, &msgDescriptor.CorrelId, sizeof(MsgParms.m_mqprCorrelId));
    
    
        memcpy(MsgParms.m_mqprCommitScope, &putMsgOptions.Options, sizeof(MsgParms.m_mqprCommitScope));
    
    
        memcpy(MsgParms.m_mqprFormat, &msgDescriptor.Format, sizeof(MsgParms.m_mqprFormat));
    
    
        memcpy(MsgParms.m_mqprPersistency, &msgDescriptor.Persistence, sizeof(MsgParms.m_mqprPersistency));
    
    
        memcpy(MsgParms.m_mqprPriority, &msgDescriptor.Priority, sizeof(MsgParms.m_mqprPriority));
    
    
        memcpy(MsgParms.m_mqprExpiry, &msgDescriptor.Expiry, sizeof(MsgParms.m_mqprExpiry)); 
    
    
        memset(MsgParms.m_mqprTargetEntity, ' ', sizeof(MsgParms.m_mqprTargetEntity));
    
    
        memset(MsgParms.m_reserved1, ' ', sizeof(MsgParms.m_reserved1));
    
    
    
    
        IMQSspSvcStdPar::SspSvcStdPar * svcStdPar = IMQSspSvcStdPar::getSingleton().sspSvcStdPar();
    
    
        //    note:
        // on OS/390 a pointer is a 31 bits quantity kept in a 4 bytes word;
        // COBOL functions (the COBOL run time system) expect(s)
        // the most significant bit of the last parameter to be set 
        TestParms * hyqcmqprParmsPtr = &MsgParms; 
        TestParms * _hyqcmqprParmsPtr = 
            (TestParms *)(((int)hyqcmqprParmsPtr) | 0x80000000);
    
    
        {
            hyqcmqprHandlerFct(
                svcStdPar,
                _hyqcmqprParmsPtr);
        }
    
    
        if (IMQSspSvcStdPar::getSingleton().rc1() == IMQSspSvcStdPar::FAILED)
        {
            throw EBCLibFctErrExcept(
                SRV_CONT_TRC_GRP,
                _callMsgTransmitFctName, 
                hyqcmqprHandlerFct, 0, 0, 0,
                IMQSspSvcStdPar::getSingleton()._rc1(),
                0,
                _FILE_, _LINE_ );
    
    
            TC_TRACE_LEAVE(SRV_CONT_TRC_GRP);
            return ;
        }
    }
    TestHandler.h

    Code:
    class TestHandler
    {
        public:
    
    
        struct TestParms
        {
            
            HyqcmqprParms(void)
                throw();
    
    
            
            // Filler                PIC X(8) VALUE 'HYQCMQPR'.
            char m_eyeCatcher[8];
    
    
            //
            // values valid for 'm_eyeCatcher'
            //
    #pragma variable(TestHandler::TestParms:: \
                validEyeCatcher, NORENT)
                static const char validEyeCatcher[];
    
    
            // Filler                PIC X(4) VALUE '0100'.
            char m_version[4];
    
    
            //
            // values valid for 'm_version'
            //
    #pragma variable(TestHandler::TestParms:: \
                version_1_0, NORENT)
                static const char version_1_0[];
    
    
    
    
            // MQPR-QueueMgr            PIC X(48) VALUE spaces.   
            char m_mqprQueueMgr[48];
    
    
            // MQPR-Queue                PIC X(48) VALUE spaces.
            char m_mqprQueue[48];
    
    
            // MQPR-ReplyQueue            PIC X(48) VALUE spaces.
            char m_mqprReplyQueue[48];
    
    
            // MQPR-Message-p            POINTER VALUE NULL.
            char m_mqprMessageP[sizeof(void *)];
    
    
            // MQPR-Message-l            PIC S9(8) COMP-5 VALUE 0.
            char m_mqprMessageL[sizeof(int)];
    
    
            // MQPR-MessageId             PIC X(24) VALUE LOW-VALUES.
            char m_messageId[24];
    
    
            // MQPR-CorrelId             PIC X(24) VALUE LOW-VALUES.
            char m_correlId[24];
    
    
            // MQPR-CommitScope            PIC S9(4) COMP-5 VALUE 0.
            char m_mqprCommitScope[sizeof(int)];
    
    
            // MQPR-Format                PIC S9(4) COMP-5 VALUE 0.
            char m_mqprFormat[sizeof(int)];
    
    
            // MQPR-Persistency            PIC S9(4) COMP-5 VALUE 0.
            char m_mqprPersistency[sizeof(int)];
    
    
            // MQPR- Priority            PIC S9(4) COMP-5 VALUE 0.
            char m_mqprPriority[sizeof(int)];
        
            // MQPR-Expiry                PIC S9(4) COMP-5 VALUE 0.
            char m_mqprExpiry[sizeof(int)];
    
    
            // MQPR-TargetEntity            PIC X(3) VALUE ' '.
            char m_mqprTargetEntity[3];
    
    
            // MQPR-FILLER                PIC X(80) VALUE LOW-VALUES.
            char m_reserved1[80];
    
    
        };
    
    
        static void callMsgTransmit(
        char * reqQName,
        IMQMsg * msg,
        bool reliably = true)
        throw(EBBaseExcept);
    
    
        static IMQSspServiceBase::SspFunction hyqcmqprHandlerFct;
    
    
    #pragma variable(TestHandler:: \
            _callMsgTransmitFctName, NORENT)
            static const char _callMsgTransmitFctName[];
    
    
    };

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    How does it not work? For example, if there is a compile error, what's the error message? If there is a logic error, write a tiny test program and tell us the test input, expected output, and actual output.

    By the way, don't use exception specifications. In particular, TestHandler::callMsgTransmit really doesn't need that catch-all: it should just access and compare the status and throw as needed, allowing exceptions from accessing the status to propagate (which you cannot reasonably do with a limited exception specification). If necessary, you could translate the exception (but then you would catch const std::exception&, not catch-all), though you shouldn't be throwing an exception only to immediately catch it to translate in the same local scope.

    Also, since control leaves the current scope upon encountering an exception, this line:
    Code:
    TC_TRACE_LEAVE(SRV_CONT_TRC_GRP);
    should be moved to before the exception is thrown. You should get rid of the return.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Code:
    // MQPR-Message-l            PIC S9(8) COMP-5 VALUE 0.
    char m_mqprMessageL[sizeof(int)];
     
    ...
    // MQPR-CommitScope            PIC S9(4) COMP-5 VALUE 0.
    char m_mqprCommitScope[sizeof(int)];
    I would first verify that your attempt at matching a C++ struct/class to what COBOL expects is actually working.
    Because you seem to be assuming that sizeof(int) is both 8 and 4.

    Separate out the prepare struct from the send struct.

    Then test the send struct functionality with a hard-coded message with minimal dependencies, to make sure it works.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Registered User
    Join Date
    Nov 2016
    Posts
    84
    But is char[4] or char[8] correct or should it int[4] and int[8]?

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    The number in () is it's width in characters.
    COBOL - Data Types - Tutorialspoint
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Memory allocation for an array in a struct pointer
    By bremenpl in forum C Programming
    Replies: 6
    Last Post: 11-27-2015, 03:59 AM
  2. Struct pointer initialization
    By pe4enka in forum C++ Programming
    Replies: 4
    Last Post: 12-06-2010, 05:16 AM
  3. memcpy with struct and pointer
    By neeraj_rn in forum C Programming
    Replies: 10
    Last Post: 08-28-2010, 07:46 AM
  4. Pointer Initialization Within A Struct
    By SMurf in forum C Programming
    Replies: 15
    Last Post: 02-09-2009, 11:27 AM
  5. Struct/pointer/memory allocation
    By markusvinsa in forum C Programming
    Replies: 16
    Last Post: 06-10-2005, 09:45 AM

Tags for this Thread