WebSphere MQ provides support for the following programming languages:
The call interface, and how you can code the calls in each of these languages, is described in WebSphere MQ Application Programming Reference.
WebSphere MQ provides data definition files to assist you with the writing of your applications. For a full description, see Appendix F, WebSphere MQ data definition files.
If you can choose which language to code your programs in, you should consider the maximum length of the messages that your programs will process. If your programs will process only messages of a known maximum length, you can code them in any of the supported programming languages. But if you do not know the maximum length of the messages the programs will have to process, the language you choose will depend on whether you are writing a CICS, IMS, or batch application:
See Appendix A, Language compilers and assemblers for the compilers that you can use to process your C programs.
Note the information in the following sections when coding WebSphere MQ programs in C.
Parameters that are input-only and of type MQHCONN, MQHOBJ, or MQLONG are passed by value; for all other parameters, the address of the parameter is passed by value.
Not all parameters that are passed by address need to be specified every time a function is invoked. Where a particular parameter is not required, a null pointer can be specified as the parameter on the function invocation, in place of the address of the parameter data. Parameters for which this is possible are identified in the call descriptions.
No parameter is returned as the value of the function; in C terminology, this means that all functions return void.
The attributes of the function are defined by the MQENTRY macro variable; the value of this macro variable depends on the environment.
The MQGET, MQPUT, and MQPUT1 functions each have one parameter that has an undefined data type, namely the Buffer parameter. This parameter is used to send and receive the application's message data.
Parameters of this sort are shown in the C examples as arrays of MQBYTE. It is valid to declare the parameters in this way, but it is usually more convenient to declare them as the particular structure that describes the layout of the data in the message. The function parameter is declared as a pointer-to-void, and so the address of any sort of data can be specified as the parameter on the function invocation.
All data types are defined by means of the typedef statement. For each data type, the corresponding pointer data type is also defined. The name of the pointer data type is the name of the elementary or structure data type prefixed with the letter "P" to denote a pointer. The attributes of the pointer are defined by the MQPOINTER macro variable; the value of this macro variable depends on the environment. The following illustrates how pointer data types are declared:
#define MQPOINTER /* depends on environment */ ... typedef MQLONG MQPOINTER PMQLONG; /* pointer to MQLONG */ typedef MQMD MQPOINTER PMQMD; /* pointer to MQMD */
Strings of binary data are declared as one of the MQBYTEn data types. Whenever you copy, compare, or set fields of this type, use the C functions memcpy, memcmp, or memset:
#include <string.h> #include "cmqc.h" MQMD MyMsgDesc; memcpy(MyMsgDesc.MsgId, /* set "MsgId" field to nulls */ MQMI_NONE, /* ...using named constant */ sizeof(MyMsgDesc.MsgId)); memset(MyMsgDesc.CorrelId, /* set "CorrelId" field to nulls */ 0x00, /* ...using a different method */ sizeof(MQBYTE24));
Do not use the string functions strcpy, strcmp, strncpy, or strncmp because these do not work correctly with data declared as MQBYTE24.
When the queue manager returns character data to the application, the queue manager always pads the character data with blanks to the defined length of the field. The queue manager does not return null-terminated strings, but you can use them in your input. Therefore, when copying, comparing, or concatenating such strings, use the string functions strncpy, strncmp, or strncat.
Do not use the string functions that require the string to be terminated by a null (strcpy, strcmp, and strcat). Also, do not use the function strlen to determine the length of the string; use instead the sizeof function to determine the length of the field.
The include file <cmqc.h> defines various macro variables that may be used to provide initial values for the structures when instances of those structures are declared. These macro variables have names of the form MQxxx_DEFAULT, where MQxxx represents the name of the structure. Use them like this:
MQMD MyMsgDesc = {MQMD_DEFAULT}; MQPMO MyPutOpts = {MQPMO_DEFAULT};
For some character fields, the MQI defines particular values that are valid (for example, for the StrucId fields or for the Format field in MQMD). For each of the valid values, two macro variables are provided:
#define MQMD_STRUC_ID "MD " #define MQFMT_STRING "MQSTR "
Use this form with the memcpy and memcmp functions.
#define MQMD_STRUC_ID_ARRAY 'M','D',' ',' ' #define MQFMT_STRING_ARRAY 'M','Q','S','T','R',' ',' ',' '
Use this form to initialize the field when an instance of the structure is declared with values different from those provided by the MQMD_DEFAULT macro variable.
When a variable number of instances of a structure are required, the instances are usually created in main storage obtained dynamically using the calloc or malloc functions.
To initialize the fields in such structures, the following technique is recommended:
MQMD ModelMsgDesc = {MQMD_DEFAULT}; /* declare model instance */
The static or auto keywords can be coded on the declaration in order to give the model instance static or dynamic lifetime, as required.
PMQMD InstancePtr; InstancePtr = malloc(sizeof(MQMD)); /* get storage for dynamic instance */
memcpy(InstancePtr,&ModelMsgDesc,sizeof(MQMD)); /* initialize dynamic instance */
For the C++ programming language, the header files contain the following additional statements that are included only when a C++ compiler is used:
#ifdef __cplusplus extern "C" { #endif /* rest of header file */ #ifdef __cplusplus } #endif
See Appendix A, Language compilers and assemblers for the compilers that you can use to process your COBOL programs.
Note the information in the following sections when coding WebSphere MQ programs in COBOL.
In this book, the names of constants are shown containing the underscore character (_) as part of the name. In COBOL, you must use the hyphen character (-) in place of the underscore.
Constants that have character-string values use the single quotation mark character (') as the string delimiter. To make the compiler accept this character, use the compiler option APOST.
The copy file CMQV contains declarations of the named constants as level-10 items. To use the constants, declare the level-01 item explicitly, then use the COPY statement to copy in the declarations of the constants:
WORKING-STORAGE SECTION. 01 MQM-CONSTANTS. COPY CMQV.
However, this method causes the constants to occupy storage in the program even if they are not referred to. If the constants are included in many separate programs within the same run unit, multiple copies of the constants will exist--this may result in a significant amount of main storage being used. You can avoid this situation by adding the GLOBAL clause to the level-01 declaration:
* Declare a global structure to hold the constants 01 MQM-CONSTANTS GLOBAL. COPY CMQV.
This causes storage to be allocated for only one set of constants within the run unit; the constants, however, can be referred to by any program within the run unit, not just the program that contains the level-01 declaration.
Not supported in WebSphere MQ for z/OS.
See Appendix A, Language compilers and assemblers for the assemblers that you can use to process your assembler-language programs.
Note the information in the following sections when coding WebSphere MQ for z/OS programs in assembler language.
In this book, the names of parameters in the descriptions of calls, and the names of fields in the descriptions of structures are shown in mixed case. In the assembler-language macros supplied with WebSphere MQ, all names are in uppercase.
The MQI is a call interface, so assembler-language programs must observe the OS linkage convention. In particular, before they issue an MQI call, assembler-language programs must point register R13 at a save area of at least 18 full words. This save area is to provide storage for the called program. It stores the registers of the caller before their contents are destroyed, and restores the contents of the caller's registers on return.
Most constants are declared as equates in macro CMQA. However, the following constants cannot be defined as equates, and these are not included when you call the macro using default options:
To include them, add the keyword EQUONLY=NO when you call the macro.
CMQA is protected against multiple declaration, so you can include it many times. However, the keyword EQUONLY takes effect only the first time the macro is included.
To allow more than one instance of a structure to be declared, the macro that generates the structure prefixes the name of each field with a user-specifiable string and an underscore character (_). Specify the string when you invoke the macro. If you do not specify a string, the macro uses the name of the structure to construct the prefix:
* Declare two object descriptors CMQODA Prefix used="MQOD_" (the default) MY_MQOD CMQODA Prefix used="MY_MQOD_"
The structure declarations in WebSphere MQ Application Programming Reference show the default prefix.
The macros can generate structure declarations in one of two forms, controlled by the DSECT parameter:
DSECT=YES | An assembler-language DSECT instruction is used to start a new data section; the structure definition immediately follows the DSECT statement. No storage is allocated, so no initialization is possible. The label on the macro invocation is used as the name of the data section; if no label is specified, the name of the structure is used. |
DSECT=NO | Assembler-language DC instructions are used to define the structure at
the current position in the routine. The fields are initialized with
values, which you can specify by coding the relevant parameters on the macro
invocation. Fields for which no values are specified on the macro
invocation are initialized with default values.
DSECT=NO is assumed if the DSECT parameter is not specified. |
You can control the appearance of the structure declaration in the assembler-language listing by means of the LIST parameter:
LIST=YES | The structure declaration appears in the assembler-language listing. |
LIST=NO | The structure declaration does not appear in the assembler-language listing. This is assumed if the LIST parameter is not specified. |
You can specify the value to be used to initialize a field in a structure by coding the name of that field (without the prefix) as a parameter on the macro invocation, accompanied by the value required.
For example, to declare a message descriptor structure with the MsgType field initialized with MQMT_REQUEST, and the ReplyToQ field initialized with the string MY_REPLY_TO_QUEUE, you could use the following code:
MY_MQMD CMQMDA MSGTYPE=MQMT_REQUEST, X REPLYTOQ=MY_REPLY_TO_QUEUE
If you specify a named constant (or equate) as a value on the macro invocation, you must use the CMQA macro to define the named constant. You must not enclose in single quotation marks (' ') values that are character strings.
WebSphere MQ uses its structures for both input and output. If you want your program to remain reenterable, you should:
To correctly initialize these working storage structures, copy a constant version of the corresponding structure to the working storage version.
Use the assembler language RENT option to help you determine if your program is reenterable.
For information on writing reenterable programs, see MVS/ESA Application Development Guide: Assembler Language Programs, GC28-1644.
If you want to use the CICS-supplied transaction, CEDF (CICS Execution Diagnostic Facility) to help you to debug your program, you must add the ,VL keyword to each CALL statement, for example:
CALL MQCONN,(NAME,HCONN,COMPCODE,REASON),MF=(E,PARMAREA),VL
The above example is reenterable assembler-language code where PARMAREA is an area in the working storage you specified.
Only supported in WebSphere MQ for iSeries.
See Appendix A, Language compilers and assemblers for the compilers that you can use to process your RPG programs.
In this book, the parameters of calls, the names of data types, the fields of structures, and the names of constants are described using their long names. In RPG, these names are abbreviated to six or fewer uppercase characters. For example, the field MsgType becomes MDMT in RPG. For more information, see WebSphere MQ for iSeries V5.3 Application Programming Reference (ILE RPG).
PL/I is supported on z/OS, OS/2, VSE/ESA, and Windows systems only.
See Appendix A, Language compilers and assemblers for the compilers that you can use to process your PL/I programs.
Note the information in the following sections when coding WebSphere MQ for z/OS programs in PL/I.
Structures are declared with the BASED attribute, and so do not occupy any storage unless the program declares one or more instances of a structure.
An instance of a structure can be declared by using the like attribute, for example:
dcl my_mqmd like MQMD; /* one instance */ dcl my_other_mqmd like MQMD; /* another one */
The structure fields are declared with the INITIAL attribute; when the like attribute is used to declare an instance of a structure, that instance inherits the initial values defined for that structure. Thus it is necessary to set only those fields where the value required is different from the initial value.
PL/I is not sensitive to case, and so the names of calls, structure fields, and constants can be coded in lowercase, uppercase, or mixed case.
The named constants are declared as macro variables; as a result, named constants which are not referenced by the program do not occupy any storage in the compiled procedure. However, the compiler option which causes the source to be processed by the macro preprocessor must be specified when the program is compiled.
All of the macro variables are character variables, even the ones which represent numeric values. Although this may seem counter intuitive, it does not result in any data-type conflict after the macro variables have been substituted by the macro processor, for example:
%dcl MQMD_STRUC_ID char; %MQMD_STRUC_ID = '''MD '''; %dcl MQMD_VERSION_1 char; %MQMD_VERSION_1 = '1';
TAL is supported on Compaq NonStop Kernel only.
See Appendix A, Language compilers and assemblers for the compilers that you can use to process your TAL programs.
Note the following when coding MQSeries for Compaq NonStop Kernel programs in TAL:
Visual Basic is only supported on Windows.
To avoid unintended translation of binary data passing between Visual Basic and WebSphere MQ, use an MQBYTE definition instead of MQSTRING. CMQB.BAS defines several new MQBYTE types which are equivalent to a C "byte" definition and uses these within WebSphere MQ structures. For example, for the MQMD (message descriptor) structure, MsgId (message identifier) is defined as MQBYTE24.
Visual Basic does not have a pointer datatype, so references to other WebSphere MQ data structures are by offset rather than pointer. You must declare a compound structure consisting of the two component structures, and specify the compound structure on the call. WebSphere MQ support for Visual Basic provides an MQCONNXAny call to make this possible and allow client applications to specify the channel properties on a client connection. It accepts an untyped structure (MQCNOCD) in place of the usual MQCNO structure.
The MQCNOCD structure is a compound structure consisting of an MQCNO followed by an MQCD. This structure is declared in the exits header file CMQXB. Use the routine MQCNOCD_DEFAULTS to initialize an MQCNOCD structure. A sample making MQCONNX calls is provided (amqscnxb.vbp).
MQCONNXAny has the same parameters as MQCONNX, except that the ConnectOpts parameter is declared as being of "Any" datatype rather than of "MQCNO" datatype. This allows the function to accept either the MQCNO or the MQCNOCD structure. This function is declared in the main header file CMQB.