C programming

Information to help you use the MQI from the C programming language.

Header files

Table 1. C header files
File Contents
CMQC Function prototypes, data types, and named constants for the main MQI
CMQXC Function prototypes, data types, and named constants for the data conversion exit
CMQEC Function prototypes, data types, and named constants for the main MQI, data conversion exit and Interface Entry Points structure (CMQEC includes CMQXC and CMQC.)
CMQSTRC Functions that convert MQI constant definitions to the text equivalent.
[z/OS]Attention: Applicable to z/OS® from IBM® MQ 9.1. Programs using this header file must be compiled with the LONGNAME compiler option.
To improve the portability of applications, code the name of the header file in lowercase on the #include preprocessor directive:
#include "cmqec.h"

Functions

You do not need to specify all parameters that are passed by address every time you invoke a function.

  • Pass parameters that are input-only and of type MQHCONN, MQHOBJ, or MQLONG by value.
  • Pass all other parameters by address.

Where a particular parameter is not required, use a null pointer 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.

Parameters with undefined data type

The Buffer parameter on the MQGET, MQPUT, and MQPUT1 functions has an undefined data type. 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. You can 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. Declare the actual function parameter as a pointer-to-void, and specify the address of any sort of data as the parameter on the function invocation.

Data types

Define all data types using the C typedef statement. For each data type, also define the corresponding pointer data type. 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. Define the attributes of the pointer using the MQPOINTER macro variable; the value of this macro variable depends on the environment. The following illustrates how to declare pointer data types:
#define MQPOINTER *                /* depends on environment */
...
typedef MQLONG MQPOINTER PMQLONG;  /* pointer to MQLONG */
typedef MQMD   MQPOINTER PMQMD;    /* pointer to MQMD */

Manipulating binary strings

Declare strings of binary data 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 ; for example:
#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 for data declared with the MQBYTEn data types.

Manipulating character strings

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.

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, 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.

Initial values for structures

The header files define various macro variables that you can use to provide initial values for the MQ structures when you declare instances of those structures.

These macro variables have names of the form MQxxx_DEFAULT, where MQxxx represents the name of the structure. They are used in the following way:
MQMD   MyMsgDesc = {MQMD_DEFAULT};
MQPMO  MyPutOpts = {MQPMO_DEFAULT};
For some character fields (for example, the StrucId fields that occur in most structures, or the Format field that occurs in MQMD), the MQI defines particular values that are valid. For each of the valid values, two macro variables are provided:
  • One macro variable defines the value as a string with a length, excluding the implied null matches, exactly the defined length of the field. For example, for the Format field in MQMD the following macro variable is provided (¬ represents a single blank character):
    #define MQFMT_STRING "MQSTR¬¬¬"
    
    Use this form with the memcpy and memcmp functions.
  • The other macro variable defines the value as an array of characters; the name of this macro variable is the name of the string form suffixed with _ARRAY. For example:
    #define MQFMT_STRING_ARRAY 'M','Q','S','T','R','¬','¬','¬'
    
    Use this form to initialize the field when you declare an instance of the structure with values different from those provided by the MQMD_DEFAULT macro variable. (This is not always necessary; in some environments you can use the string form of the value in both situations. However, you can use the array form for declarations, because this is required for compatibility with the C++ programming language.)

Initial values for dynamic structures

When a variable number of instances of a structure is required, the instances are typically created in main storage obtained dynamically using the calloc or malloc functions. To initialize the fields in such structures, consider the following technique:
  1. Declare an instance of the structure using the appropriate MQxxx_DEFAULT macro variable to initialize the structure. This instance becomes the model for other instances:
    MQMD Model = {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.
  2. Use the calloc or malloc functions to obtain storage for a dynamic instance of the structure:
    PMQMD Instance;
    Instance = malloc(sizeof(MQMD)); /* get storage for dynamic instance */
    
  3. Use the memcpy function to copy the model instance to the dynamic instance:
    memcpy(Instance,&Model,sizeof(MQMD)); /* initialize dynamic instance */
    

Use from C++

For the C++ programming language, the header files contain the following additional statements that are included only when you use a C++ compiler:
#ifdef __cplusplus
  extern "C" {
#endif

/* rest of header file */

#ifdef __cplusplus
  }
#endif

Notation conventions

This information shows how to invoke the functions and declare parameters.

In some cases, the parameters are arrays with a size that is not fixed. For these, a lowercase n is used to represent a numeric constant. When you code the declaration for that parameter, replace the n with the numeric value required.