Notes C API & C++11+ & ReactiveX & Qt #6 ~ Notes C API関数の基本

前回は、Qtの翻訳機能について少し触れました。今回は、このプログラムで肝となるNotes C API「NSFGetServerLatency」についてお話しします。

v0.0.1のソースコードを実行すると、次のような出力が得られます。

f:id:takahide-kondoh:20181103132108p:plain

2行目、3行目はAPIがユーザにパスワードの入力を促している様子です(GUIアプリの場合はダイアログボックスが表示されます)。 また、以下のシグネチャを・・・

// 待ち時間を読み取る場合はこのシグネチャを有効にする。
//#define GET_LATENCY_TIME

次のようにコメントを外すと・・・

// 待ち時間を読み取る場合はこのシグネチャを有効にする。
#define GET_LATENCY_TIME

このような出力に変化します。

f:id:takahide-kondoh:20181103132754p:plain

目的のサーバのバージョン(ビルド番号)に加えて、2種類のLatency(レイテンシ、待ち時間)をミリ秒で表示するようになります。

では、NSFGetServerLatency関数のシグネチャについて見てみましょう。

// nsfdb.h

STATUS LNPUBLIC NSFGetServerLatency(
  char far *ServerName,
  DWORD Timeout,
  DWORD far *retClientToServerMS,
  DWORD far *retServerToClientMS,
  WORD far *ServerVersion
);
  • ServerName: (入力)目的のサーバ名を指定します。LMBCSですが、マルチバイト文字を含まなければシングルバイト文字列のまま指定できます。
  • Timeout: (入力)サーバからの応答を待機する時間で、ミリ秒で指定します。0を指定すると、環境が持っているデフォルトのタイムアウト時間が使用されます。
  • retClientToServerMS: (出力)クライアントからサーバへの応答時間(ミリ秒)を取得します。
  • retServerToClientMS: (出力)サーバからクライアントへの応答時間(ミリ秒)を取得します。
  • ServerVersion: (出力)サーバのバージョンをビルド番号で取得します。「405」は「9.0.1」を表します。@関数の@Versionと同じです。
  • STATUS戻り値: 実行結果を返します。成功すればNOERROR(0)を、失敗すればエラー番号を返します。

使い方としては次のようになります。

DWORD clientToServerMS, serverToClientMS;
WORD serverVersion;
STATUS status = NSFGetServerLatency(
  const_cast<char*>("Your/Server/Name"),
  static_cast<DWORD>(0),
  &clientToServerMS,
  &serverToClientMS,
  &serverVersion
);

Notes C APIでよくある問題として、「const_cast問題」があります。const_castキャスト演算子とは、定数属性「const」「volatile」などがついた型から定数属性を外します。関数の入力用引数は、出力用引数に比べて変化することがないので、const属性を付加するのが普通ですが、Notes C APIの関数では、理由は不明ですが、しばしば入力値にconst属性がついていないものがあります。上述のように、const_castを使わずに定数ポインタを指定してしまうと、コンパイルエラーを起こしてしまうので、面倒ですが、const_castを追加する必要があります。

Notes C API関数の大部分は、戻り値として「STATUS」値を返します。元をたどると符号なし2バイト整数になります。STATUS値は関数が実行に成功すると0(シグネチャ「NOERROR」)を、失敗すると0以外のエラー値を表します。ただし上位2ビットはフラグとして機能するので、正確なエラー値を取得するにはERRマクロでマスクする必要があります。

STATUS error = ERR(status);

関数の戻り値は、STATUSによる関数実行の成否に使われてしまうため、レイテンシやバージョン番号などの出力要素は、ポインタで指定された引数で取得することになります。

アドインを開発している分にはNotes C API関数は普通に利用できますが、NotesクライアントやDominoサーバから独立したプロセスでプログラムを動かしている場合、Notes C APIは初期化/終了処理を必要とします。

STATUS LNPUBLIC NotesInitExtended (int argc, char far * far *argv);
void   LNPUBLIC NotesTerm (void);

Notes C API関数の実行に先立ち、NotesInitExtendedを実行する必要があります。argc、argvはmain関数の引数をそのまま渡します。プログラム(プロセス)を終了する前にNotesTermを実行します。

(続く)