|
I am trying to extract the receiver information using the Receive_Message (QMHRCVPM) API. I am specifing format RCVM0300 and my Message_Text field is 1024 bytes. When I look at the Message_Text in debug, I only see the sending procedure name. The receiver name is nowhere to be found.
That's because when you display a data structure in the debugger, it lists each subfield of the data structure, with it's contents. You only have ONE SUBFIELD DEFINED, so it only shows that subfield! That subfield is coded in the wrong place, so what you see is the wrong data.
If you (in teh green screen debugger) type "eval Message_text:x" on the command line, it'll show the whole data structure in hex. (rather than the subfields)
So that's why you can't see the results in the debugger -- now on to what's wrong with your code:
a) You have a variable called API_Error_Code that's defined as 144A and initialized as *Blanks. You pass that as the error code parameter to the two APIs that you call. This is wrong. The APIs aren't expecting a big long blank string as a parameter for the error code.
In fact, what they're expecting is a 4-byte binary integer containing the length of the structure, followed by at least one other 4-byte binary integer.
Since blanks in EBCDIC are x'40', the first 4 bytes of your "error code" are x'40404040' -- convert that to decimal and you get 1077952576. That's how long the API thinks your error code data structure is! Over 1 gb!!
If it happens to try to write more than 144 bytes to it, it'll start corrupting memory, and you'll end up with a really messed up environment. Why oh why did you think it was okay to pass a blank string to the API?
You have a definition called "Error_Ds" in your code that you're not using -- this definition is the correct one for calling these APIs -- EXCEPT -- you're not inizializing the Bytes_Provided field. Since data structures in RPG are all initialized to *blanks, this'll give you the same problem unless you add code to initialize the Bytes_provided field. Though, it's a moot point, since you're not passing it to the APIs anyway!
Even if you did pass it, you're not checking it after the API call, so even if the API failed, you wouldn't know about it!
That's why my example had a data structure with two 10I 0 fields, both initialized to zero. If the API fails, and the Bytes_Provided field is 0, it'll send you an *ESCAPE message that you can catch in a *PSSR or MONITOR statement.
b) Your Message_Text variable is wrong. It should be a data structure containing a bunch of fields. Some of those fields are in variable positions.
You can't just hard-code something in position 180.The API sends some parameters that TELL YOU where the variable-length fields start and end. You can't just ignore what it tells you and assume that it'll always be 180! That doesn't make sense.
That's why my code does the following: p_SndRcvInfo = %addr(RCVM0300.VarStart) + RCVM0300.MsgDtaLen + RCVM0300.MsgLen + RCVM0300.MsgHlpLen;Note that the SndRcvInfo data structure is BASED on the p_SndRcvInfo pointer. When I add those fields together, I'm calculating the right place in memory to put that data structure. That way, I'm not just ignoring what the API tells me for the position, but instead, I'm making sure that the procedure name is extracted from the right place.
I hope this helps!
As an Amazon Associate we earn from qualifying purchases.
This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].
Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.