6.4.1 C言語またはC++言語のコーディング
C言語またはC++言語でアプリケーションを記述するときには,次に示す項目について検討してください。
- 〈この項の構成〉
(1) MQI命令のパラメタ
入力専用であり,かつMQHCONN,MQHOBJ,またはMQLONG型のパラメタは値を渡します。その他のパラメタでは,パラメタのアドレスを渡します。
アドレスを渡すパラメタについては,関数発行のたびに渡す必要はありません。パラメタが不要な場合には,パラメタデータのアドレスの代わりにヌルポインタを関数パラメタとして渡せます。該当するパラメタが何であるかについては,各命令の説明を参照してください。
関数の値としてパラメタが返されることはありません。C言語またはC++言語ではすべての関数がvoidを返します。
(2) 未定義データタイプのパラメタ
MQGET命令,MQPUT命令,およびMQPUT1命令は,未定義のデータタイプであるBufferパラメタを一つ持ちます。このパラメタはアプリケーションのメッセージデータを送受信するのに使用されます。
このパラメタはMQBYTE型の配列で定義できます。しかし,通常はメッセージ内のデータ構成を表す構造体で宣言する方が便利です。関数パラメタはvoidポインタで宣言されているので,関数発行時にどのデータタイプのアドレスでも指定できます。
(3) データタイプ
すべてのデータタイプはtypedefステートメントで定義されます。各データタイプには,対応するポインタデータタイプも定義されます。ポインタデータタイプの名前は,基本データタイプまたは構造体データタイプの名前の先頭にポインタを表す"P"を付加した名前です。ポインタの属性はMQPOINTERマクロ変数で定義されます。マクロ変数の値は環境によって異なります。ポインタデータタイプの宣言について次に示します。
#define MQPOINTER /* 環境依存 */ ... typedef MQLONG MQPOINTER PMQLONG; /* MQLONGのポインタ */ typedef MQMD MQPOINTER PMQMD; /* MQMDのポインタ */
(4) 2進文字列の操作
2進文字列はMQBYTEnデータタイプとして宣言されます。このデータタイプをコピー,比較,および設定する場合には,memcpy(),memcmp(),およびmemset()を使用してください。
#include <string.h> #include "cmqc.h" MQMD MyMsgDesc; memcpy(MyMsgDesc.MsgId, /* MsgIdフィールドにヌルを設定 */ MQMI_NONE, /* 名前付き定数を使用する場合 */ sizeof(MyMsgDesc.MsgId)); memcpy(MyMsgDesc.CorrelId, /* CorrelIdフィールドにヌルを設定 */ 0x00, /* 違う方法 */ sizeof(MQBYTE24));
文字列関数strcpy(),strcmp(),strncpy(),およびstrncmp()は使用しないでください。MQBYTE24で宣言されているデータを正しく処理できません。
(5) 文字列の操作
キューマネジャが文字データをアプリケーションに返すときは,定義された長さになるように文字データを空白で埋めます。キューマネジャがヌル文字で終わる文字列を返すことはありません。しかし,ユーザ入力で使用することは可能です。そのため,そのような文字列をコピー,比較,または結合するときには文字列関数strncpy(),strncmp(),またはstrncat()を使用してください。
文字列の終わりにヌルが必要な文字列関数(strcpy(),strcmp(),またはstrcat())は使用しないでください。また,文字列の長さを決定するのにstrlen()は使用しないでください。代わりにsizeof()を使用してください。
(6) 構造体の初期値
インクルードファイルcmqc.hは,構造体のインスタンスが宣言されたときの初期値を設定するマクロ変数を定義します。これらのマクロ変数はMQxxx_DEFAULTという形式の名前です。MQxxxは構造体の名前です。例えば,次に示すとおり使用します。
MQMD MyMsgDesc = {MQMD_DEFAULT}; MQMD MyPutOpts = {MQPMO_DEFAULT};
MQIで有効値を定義する文字フィールド(MQMD構造体のStrucId,Formatフィールドなど)もあります。有効値として,二つのマクロ変数が提供されます。
-
ヌルを除くと,フィールドに定義される長さと一致するような文字列の値を定義するマクロ変数。例を次に示します。
#define MQMD_STRUC_ID "MD " #define MQFMT_STRING "MQSTR "
この形式をmemcpy()およびmemcmp()で使用してください。
-
文字の配列として値を定義するマクロ変数。名前の末尾は"_ARRAY"です。例を次に示します。
#define MQMD_STRUC_ID_ARRAY 'M', 'D', ' ', ' ' #define MQFMT_STRING_ARRAY 'M', 'Q', 'S', 'T', 'R', ' ', ' ', ' '
MQMD_DEFAULTマクロ変数の提供する値とは異なる値で構造体のインスタンスを宣言するときには,この形式を使用してフィールドを初期化してください。
(7) 動的構造体の初期値
複数の構造体のインスタンスが必要な場合には,通常は,calloc()またはmalloc()を使用して動的に取得した領域にインスタンスが作成されます。このような構造体のフィールドを初期化するには,次に示す方法をお勧めします。
-
適切なMQxxx_DEFAULTマクロ変数を使用して初期化して,構造体のインスタンスを宣言します。このインスタンスが他インスタンスのモデルとなります。
MQMD ModelMsgDesc = {MQMD_DEFAULT}; /* モデルインスタンスの宣言 */
必要に応じて宣言にstaticまたはautoを使用して,モデルインスタンスに静的または動的なスコープを設定することもできます。
-
calloc()またはmalloc()を使用して,構造体の動的インスタンスの領域を取得します。
PMQMD InstancePtr; InstancePtr = malloc(sizeof(MQMD)); /* 動的インスタンスの領域を取得 */
-
memcpy()を使用してモデルインスタンスを動的インスタンスにコピーします。
memcpy(InstancePtr, &ModelMsgDesc, sizeof(MQMD)); /* 動的インスタンスの初期化 */
(8) C++コンパイラの使用
C++コンパイラの使用時だけにインクルードされるステートメントが,ヘッダファイルにあります。
#ifdef __cplusplus extern "C" { #endif /* ヘッダファイルの残り */ #ifdef __cplusplus } #endif