采用 C 进行编码

在 C 中对 IBM® MQ 程序进行编码时,请注意以下部分中的信息。

MQI 调用的参数

只输入且类型为 MQHCONN、MQHOBJ、MQHMSG 或 MQLONG 的参数按值传递;对于所有其他参数,参数的地址按值传递。

每次调用函数时,并非所有按地址传递的参数都需要指定。 在无需特定参数的情况下,可以在调用函数时将空指针指定为参数,从而代替参数数据的地址。 可以进行此操作的参数在调用描述中被识别。

没有任何参数作为函数值返回;在 C 术语中,这意味着所有函数都返回空。

函数的属性由 MQENTRY 宏变量定义;此宏变量的值取决于环境。

具有未定义数据类型的参数

MQGET、MQPUT 和 MQPUT1 函数各自具有未定义数据类型的 Buffer 参数。 此参数用于发送和接收应用程序的消息数据。

此类参数在 C 示例中显示为 MQBYTE 的数组。 您可以通过此方式声明参数,但是将其声明为描述消息中数据布局的结构,通常更为方便。 函数参数声明为空指针,因此在调用函数时可以将任何数据的地址指定为参数。

数据类型

所有数据类型都使用 typedef 语句进行定义。

对于各数据类型,还会定义对应的指针数据类型。 指针数据类型的名称是以字母 P(表示指针)为前缀的基本或结构数据类型的名称。 指针的属性由 MQPOINTER 宏变量定义;此宏变量的值取决于环境。 以下代码说明如何声明指针数据类型:
#define MQPOINTER                   /* depends on environment */
...
typedef MQLONG  MQPOINTER PMQLONG;  /* pointer to MQLONG */
typedef MQMD   MQPOINTER PMQMD;     /* pointer to MQMD */

处理二进制字符串

二进制数据的字符串声明为 MQBYTEn 数据类型之一。

只要复制、比较或设置此类型的字段,就请使用 C 函数 memcpymemcmpmemset
#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));

请勿使用字符串函数 strcpy、strcmp、strncpy 或 strncmp,因为这些函数在数据声明为 MQBYTE24 时无法正常工作。

处理字符串

当队列管理器将字符数据返回到应用程序时,队列管理器始终根据字段的已定义长度来使用空白填充字符数据。 队列管理器不返回以 null 结束的字符串,但是可以在输入中使用这些字符串。 因此,在复制、比较或并置此类字符串时,请使用字符串函数 strncpy、strncmp 或 strncat。

请勿使用要求字符串以 null 结束的字符串函数(strcpy、strcmp 和 strcat)。 此外,请勿使用函数 strlen 来确定字符串的长度;改用 sizeof 函数来确定字段的长度。

结构的初始值

包含文件 <cmqc.h> 定义可在声明结构的实例时用于提供这些结构的初始值的各种宏变量。 这些宏变量具有 MQxxx_DEFAULT 形式的名称,其中 MQxxx 表示结构的名称。 请按如下对其进行使用:
MQMD   MyMsgDesc = {MQMD_DEFAULT};
MQPMO  MyPutOpts = {MQPMO_DEFAULT};
对于某些字符字段,MQI 定义有效的特定值(例如,对于 StrucId 字段或对于 MQMD 中的 Format 字段)。 对于各有效值,将会提供两个宏变量:
  • 一个宏变量将值定义为具有某个长度的字符串(暗含的 null 除外),该长度与字段的已定义长度相匹配。 在以下示例中,符号 ¬ 表示单个空白字符:
    #define MQMD_STRUC_ID "MD¬¬"
    #define MQFMT_STRING "MQSTR¬¬¬"
    
    将此形式用于 memcpy 和 memcmp 函数。
  • 另一个宏变量将值定义为 char 的数组;此宏变量的名称是以 _ARRAY 为后缀的字符串形式的名称。 例如:
    #define MQMD_STRUC_ID_ARRAY 'M','D','¬','¬'
    #define MQFMT_STRING_ARRAY 'M','Q','S','T','R','¬','¬','¬'
    
    当使用与 MQMD_DEFAULT 宏变量所提供的值不同的值来声明结构的实例时,使用此形式来初始化字段。

动态结构的初始值

当需要可变数量的结构实例时,通常在使用 calloc 或 malloc 函数动态获取的主存储器中创建实例。

要初始化此类结构中的字段,建议使用以下方法:
  1. 使用相应的 MQxxx_DEFAULT 宏变量声明结构的实例以初始化该结构。 此实例成为其他实例的模型
    MQMD ModelMsgDesc = {MQMD_DEFAULT};
                                      /* declare model instance */
    
    对声明中的 static 或 auto 关键字进行编码,以根据需要提供模型实例静态或动态生命周期。
  2. 使用 calloc 或 malloc 函数获取结构的动态实例的存储器:
    PMQMD InstancePtr;
    InstancePtr = malloc(sizeof(MQMD));
                                      /* get storage for dynamic instance */
    
  3. 使用 memcpy 函数将模型实例复制到动态实例:
    memcpy(InstancePtr,&ModelMsgDesc,sizeof(MQMD));
                                      /* initialize dynamic instance */
    

从 C++ 使用

对于 C++ 编程语言,头文件包含仅当使用 C++ 编译器时才含有的以下附加语句:
#ifdef __cplusplus
  extern "C" {
#endif

/* rest of header file */

#ifdef __cplusplus
  }
#endif