情報を戻す情報カタログ・マネージャー API 呼び出しは、その情報を出力構造に収めます。
出力構造を読むためには、構造の各部分が他の部分の意味を定義しているため、 その構造全体を 1 つのものとしてとらえてください。
オブジェクト・インスタンスのリストを戻す API 呼び出しの場合、 オブジェクト域には、各特性ごとに複数の値が含まれている可能性があります。 このオブジェクト域には、定義域で定義された特性をマップするための値の 集合が 2 つ以上含まれることがあります。
出力構造内の値を読むには、API 呼び出しで戻されたポインターを使用して、 その構造を指す 2 つ以上のポインターを定義してください。
ユーザーのプログラムは、出力構造を作成する API 呼び出しを出す場合、 NULL ポインターのアドレスを含むポインターを定義して、この定義済みポインターを パラメーターとして API 呼び出しに渡す必要があります。 API 機能はこの NULL ポインターにその出力構造のアドレスを割り当てます。
ユーザーは、この構造のヘッダー域と定義域を順に処理する 2 番目のポインター と、オブジェクト域を順に処理する 3 番目のポインターも定義する必要があります。
図 27 で示す pOutStruct は、出力構造の先頭を指すポインターです。 そのあとで、ヘッダー域と定義域を順に読み取るための pReadStruct を定義し、 オブジェクト域を順に読み取る pObjArea を定義することができます。
![]() |
ユーザーの必要に応じて、構造の値を戻されたとおりの順で読み取ることも、 特定の値を探索することもできます。 いずれの場合にも、次のことを行う必要があります。
情報カタログ・マネージャーでは、出力構造を読むために必要な多くの値の長さと有効な値を定義 する DG2API.H というヘッダー・ファイルが提供されています。 これらの長さを使用して、ヘッダー域、定義域、およびオブジェクト域を順に読む ために必要な C 言語コードを作成することができます。
DG2API.H ファイルで定義されている内容の完全なリストについては、 付録 B, 情報カタログ・マネージャー API ヘッダー・ファイル − DG2APIHを参照してください。
API 呼び出しのなかには不特定数の特性を戻すものがあるため、その数を 計算することが必要になります。
API 呼び出しによって戻されたポインター・アドレスを使用して、 出力構造の先頭を指すようにポインターをセットしてください。
定義域内の特性の数を計算するために、ヘッダー域の 定義の長さ域 (バイト 8-15) の数値を定義域の 個別レコードの長さ (160) で割ってください。 この計算を行うためには、定義の長さの文字列を整数値に変換する必要があります。
DG2API.H では、この計算を行いやすくするために、 変数 FLG_DEFINITION_SIZE が提供されています。
特性の数 = 定義の長さの整数値 / FLG_DEFINITION_SIZE |
出力構造に戻された値の集合の数を計算するためには、図 30 に示すように、図 29 に示す オブジェクト域の項目カウントを構造内の特性の数で割ってください。
![]() |
値の集合の数 = オブジェクト域の項目カウント / 特性の数 |
ヘッダー域のフィールドは文字形式なので、図 30 の計算で使用されるときには、数値形式に変換されなければなりません。図 30 の計算にたどりつくためには、DG2API.H で定義された構造を使用することができます。
特性のデータ・タイプと長さを読み取るためには、ポインターを定義して、 定義域の正しい値を読むためのポインター算術計算を行ってください。 図 31 では最初の特性のデータ・タイプと長さの位置が強調表示されています。
![]() |
定義域の最初の特性のデータ・タイプを読むには、図 32 に 示すように、最初の定義レコードのヘッダー域および特性名のフィールドの長さ を、出力構造を指すフィールドの位置に加算してください。
pLocationOfDataType = pOutStruct + FLG_HEADER_SIZE + FLG_D_PROPNM_LEN |
pOutStruct は出力構造を指すポインターを表し、FLG_HEADER_SIZE は ヘッダー域の長さを表し、FLG_D_PROPNM_LEN は特性名フィールドの長さを表します。 これで、この位置にある値を別の変数に保管できるようになります。
定義域の最初の特性のデータ長を読むには、図 33 に示す ように、計算によって得られたポインターにデータ・タイプ・フィールドの 長さを加算して、データ・タイプの位置を求めてください。
pLocationOfDataLen = pLocationOfDataType + FLG_D_DATATYP_LEN |
pLocationOfDataType は定義レコード内のデータ・タイプ・フィールド を指すポインターであり、FLG_D_DATATYP_LEN はデータ・タイプ・フィールドの 長さです。
その他の特性のデータ・タイプと長さを読むには、さらにオフセット値を加算します。 次の特性のデータ・タイプ・フィールドを求めるには、図 34 に 示すように、現在の特性のデータ・タイプを指すポインターに、1 つのデータ・レコード 全体の長さ (160) を加えてください。
pLocationOfDataType = pLocationOfDataType + FLG_DEFINITION_SIZE |
FLG_DEFINITION_SIZE は 160 バイトです。
オブジェクト域の値を読むには、ポインター算術計算によってその位置を 求める必要があります。 位置を正しく計算するためには、特性のデータ・タイプと長さが分からなければ なりません。
pObjArea = pOutStructure + FLG_HEADER_SIZE + (FLG_DEFINITION_SIZE × number_of_properties) |
FLG_HEADER_SIZE はヘッダー域の長さであり、FLG_DEFINITION_SIZE は定義域 内の 1 つのレコードの長さです。
図 36 に示すように、現行値の実際の長さをポインターに 加算して、オブジェクト域内の次の値に移動します。
pObjValue = pObjArea + 値の実際の長さ |
図 37 は、オブジェクト域の先頭から開始して、VARCHAR 値の 長さを読み、ポインターをその値自体の先頭に移動させ、その値を読み、さらに 次の値に進む方法を示しています。
![]() |
DG2SAMP.C プログラムは、ユーザーからオブジェクト・タイプ名を入手してか ら FLGListObjTypes 呼び出しを出して、情報カタログ・データベースで使用可能なオブジェクト・タイプ のリストを検索します。 このプログラムは、ユーザーが指定したオブジェクト・タイプの外部名と、FLGListObjTypes が出力構造に入れて戻した名前を突き合わせます。
図 38 は、FLGListObjTypes の API 呼び出しによって作成される 出力構造の形式を示しています。
![]() |
図 39 は、このプログラムがユーザーによって指定された 値を読み取ってその長さを計算するようすを示しています。 この図は、プログラムが出力構造内の値を NULL 文字で終了するストリングに コピーし、オブジェクト域内の値の集合の数を計算する方法も示しています。
gets(pszObjName); (1) ulTypeLen = strlen(pszObjName); (2) memcpy(&pszObjEntryCount, pListStruct->pchHObjEntryCount, FLG_H_OBJAREAENT_LEN); (3) memcpy(&pszDefLength, pListStruct->pchHDefLength, FLG_H_DEFAREA_LEN); (4) ulCount = (atoi(pszObjEntryCount) / (atoi(pszDefLength) / FLG_DEFINITION_SIZE)); (5) |
図 39 に示したコードは、以下のステップを実行します。
図 40 に示すコードは、オブジェクト域の先頭に ポインターを割り当てます。
この例では、FLGListObjTypes の出力は常に 3 つの同じ特性を持つため、プログラムは 特性の数、データ・タイプ、およびデータ長を判別する必要がありません。
図 40. DG2SAMP.C: オブジェクト域の先頭へのポインターの割り当て
ulPosition = 0; (1) pCurrPos = ((UCHAR *)pListStruct + FLG_HEADER_SIZE + ulDefLen); (2) |
図 40 に示したコードは、以下のステップを実行します。
図 41 に示すコードは、オブジェクト域内でポインター を移動させ、ユーザーが指定した名前に一致するオブジェクト・タイプ名の 検出を試みます。
図 41. DG2SAMP.C: オブジェクト・タイプ名とオブジェクト域内のオブジェクト・タイプ名の突き合わせ
while (fNotFound && (ulPosition < ulCount)) (1) { ulPosition = (ulPosition + 1); memcpy(&pszObjTypeId, (void *) pCurrPos, FLG_H_OBJTYPID_LEN); (2) pCurrPos = pCurrPos + FLG_H_OBJTYPID_LEN; (3) memcpy(&pszLength, (void *)pCurrPos, FLG_VARIABLE_DATA_LENGTH_LEN);(4) ulLength = atoi(pszLength); (5) pCurrPos = pCurrPos + FLG_VARIABLE_DATA_LENGTH_LEN; (6) strncpy (pszObjectName, (void *)pCurrPos, ulLength); (7) pszObjectName[ulLength]¨ = NULLCHAR; (8) if (!(strcmp(pszObjName, pszObjectName))) (9) { fNotFound = FALSE; printf ("The object type ID for %s is %s.\n\n", pszObjName, pszObjTypeId); } else { // Move temporary pointer to the next object pCurrPos = pCurrPos + ulLength + FLG_DPNAME_LEN; (10) } } |
図 41 に示したコードは、以下のステップを実行します。