I was porting the pymqi code, which provides a Python interface to IBM MQ, to z/OS.
I’ve documented getting the code to build. I also had challenges trying to use it.
The code runs as ASCII!
When my C extension was built, it gets built with the ASCII option. This means any character constants are in ASCII not, EBCDIC.
My python program had
import sys
sys.path.append(‘./’)
import pymqi
queue_manager = ‘AB12’
qmgr = pymqi.connect(queue_manager)
qmgr.disconnect()
When my C code got to see the AB12 value, it was in ASCII. When the code tried to connect to the queue manager, it return with name error. This was because the value was in ASCII, and the C code expected EBCDIC.
You can take see if the program has been compiled with the ASCII flag using
#ifdef __CHARSET_LIB
… It is has been compiled with option ASCII
#else
…
If you use printf to display the queue manager name it will print AB12. If you display it in hex you will be 41423132 where A is x41, B is x42, 1 is x31 is 2 is x32.
In your C program you can convert this using the c function a2e with length option, for example
char EQMName[4];
memcpy(&EQMName[0],QMname,4);
__a2e_l(&EQMName[0],sizeof(EQMName));// then use &EQMName
Converting from ASCII to EBCDIC in Python.
Within Python you have strings stored as Unicode, and byte data. If you have a byte array with x41423132 (the ASCII equivalent to AB12). You can get this in the EBCDIC format using
a=b’41423132′ # this is the byte array
m = a.decode(“ascii”) # this creates a character string
e = m.encode(‘cp500’) # this create the new byte array of the EBCDIC version .. or xC1C2F1F2
In Python you convert from a dictionary of fields into a “control block” using the pack function. You can use the “e” value above in this.
MQ control blocks have a 4 character eye catcher at the front eg “OD “. If you use the pack function and pass “OD ” you will pass the ASCII version. You will need to do the decode(‘ascii’) encode(‘CP500’) to create the EBCDIC version.
Similarly passing an object such as MQ queue name, will need to be converted to the EBCDIC version.
Converting from EBCDIC to ASCII
If you want to return character data from your C program to Python, you will need to the opposite.
For example m is a byte array retuned back from the load module.
#v is has the value b’C1C2F2F3′ (AB23)
m = v.decode(“cp500”)
a = m.encode(‘ascii’)# a now has b’41423132′ which is the ascii equivilant