C400

42. API エラー報告

API を使用するときにも API のエラーのモニター処理をしていないとそのまま、あたかもエラーが

起こらなかったのかのように処理を進めていくと予測できない結果を生じる。

またエラーの発見が困難になってしまうのでAPI の実行にも、必ずエラー処理を行うようにして

おきたいものである。

API のエラー・コードはシステムAPI 解説書に説明されているが説明が適切でない部分があるため、

ユーザーにとってややわかりにくいものとなっている。

ここでは、その意味と使用方法を解説する。

さて、API のエラー・コードはすべて統一されていて次の形式をしている。

開始位置 使用 タイプ 項目の説明
1 入力 BIN(4) エラー・コード全体の長さ (=116)
5 出力 BIN(4) API から戻された長さ
9 出力 CHR(7) エラー・メッセージ ID (MSGID)
16 出力 CHR(1) 予約済み(未使用)
17 出力 CHR(100) メッセージ・データ (MSGDTA)
【 解説 】

エラーがなくAPI が正常に終了した場合には、「API から戻された長さ」は 0 であり、

「API から戻された長さ」が 0 でない場合は、エラーが発生したものと判別することができる。

次にエラーが発生したとすると「エラー・メッセージ ID 」には QCPFMSG のメッセージ識別コード(MSGID) が戻る。

そして「メッセージ・データ」が、このエラー・メッセージに対するメッセージ・データとして戻る

のである。

このことが IBM システムAPI 解説書 には明記されていないため、読み手が理解しにくい

状況になっているのと同時に APIエラー処理の例がほとんどない。

以上のことを理解した上で次のサンプルC/400ソースを参照して頂きたい。

【 サンブルC/400 】
#include <stdio.h>                                                    
#include <stdlib.h>                                                   
#include <string.h>                                                   
#include <QUSCRTUS.h>                                                 
#include <QMHRTVM.h>                                                  
                                                                      
#define TRUE         0                                                
#define FALSE       -1                                                
typedef struct {                                                      
   int  BYTESPRO;                                                     
   int  BYTESAVL;                                                     
   char MSGID[7];                                                     
   char RESRVD;                                                       
   char EXCPDATA[100];                                                
} ERRSTRUCTURE;     /* Define the error return structure            */
ERRSTRUCTURE  errcode;/* Error Code Structure for RCVMSG      */      
                                                                      
void main(void){                                                      
  char msgid[8], msgdta[100];                                         
  int  msglen, msgdtalen, pos;                                        
  char* Message;                                                   
  char* ptr;                                                       
  typedef struct {                                                 
    Qmh_Rtvm_RTVM0100_t  rtvm0100;                                 
    char msg[512];                                                 
  } ERRMSG;                                                        
  ERRMSG errmsg;                                                   
                                                                   
  errcode.BYTESPRO = 160;                                          
  errcode.BYTESAVL  = 0;                                           
  QUSCRTUS("MYSPACE   ATEMP     ", "PF        ", 1000, " ",        
                 "*ALL      ", "INZLIB ユーザー空間 ",             
                 "*YES      ", &errcode);                          
  if(errcode.BYTESAVL != 0){/* APIERR */                           
    memset(msgid, 0, sizeof(msgid));                               
    memcpy(msgid, errcode.MSGID, 7);                               
    msgid[7] = 0x00;                                               
    memset(msgdta, 0, sizeof(msgdta));                             
    memcpy(msgdta, errcode.EXCPDATA, 100);                         
    msglen = sizeof(ERRMSG);                                       
    msgdtalen = strlen(msgdta);                                    
    memset(&errmsg, 0, sizeof(ERRMSG));                             
    QMHRTVM(&errmsg,  msglen, "RTVM0100", msgid, "QCPFMSG   *LIBL   
          msgdta, msgdtalen, "*YES      ", "*YES      ", &errcode); 
    printf("ERROR = %sn", errmsg.msg);                             
    getchar();                                                      
  }/* APIERR */                                                     
}

【 解説 】

この API : QUSCRTUS によるユーザー・スペースの作成はライブラリー名を ATEMP という

名前にして意図的にエラーが発生するようにしている。

API エラー・コードの構造に合わせて MSGID と MSGDTA を取り出して API: QMHRTVM

を使ってメッセージに組み立てて、printf で出力している。