Notes C API探訪: STATUS(データ型)その2
STATUS型については、以前の記事で意味や構造などを紹介しました。
STATUS型には関数が処理した結果、正しく終了したのか、エラーが起きた場合はどんなエラーが起きたのかを伝える役目があります。STATUS値にエラー検出用マクロERRを通した時、NOERROR値と同じであれば正しく処理されたことがわかります。一方、NOERROR値ではなかった時に何かしらのエラーが起きたことがわかります。
STATUS status = SomethingNotesAPIFunction();
if (ERR(status) == NOERROR) { /* Processed correctly. */ }
else { /* An error occurred. */ }
しかし、それはただの数値に過ぎません。どんなエラーが起きたのか、人間が呼んでわかる文字列にしてくれるのがOSLoadString関数です。
OSLoadString
OSLoadString関数は、ERRマクロでマスクされたSTATUS値を渡すと、エラーコードに対応したエラー文字列を返します。
#include <osmisc.h>
WORD LNPUBLIC OSLoadString (
HMODULE hModule,
STATUS StringCode,
char far *retBuffer,
WORD BufferLength);
#include <misc.h>
#if (defined(ND64) || defined(NDUNIX64)) && defined(USE_LARGE_MAXSPRINTF)
#define MAXSPRINTF 1024
#else
#define MAXSPRINTF 256
#endif
hModuleは、モジュールハンドルを指定します。Unix系では常にNULLHANDLEにします。Windows系でも、基本はNULLHANDLEですが、Windows特有の「文字列リソース」にアクセスすることを目的に、ハンドルを渡してそのモジュールからリソースを得ることもできます。「OSLoadString」という名目に「エラー文字列の取得だけが目的でない」みたいな意味が垣間見える気がします。とは言え、目的がNotes/Dominoのエラー文字列であれば、NULLHANDLEで十分です。
StringCodeは、ERRマクロでマスクされたSTATUS値を指定します。
retBufferとBufferLengthには、エラー文字列を受け取るバッファへのポインタとサイズを指定します。なお、バッファサイズは定数MAXSPRINTFを使えば十分な領域を確保できます。
サンプルコード
#include <global.h>
#include <osmisc.h>
#include <nsfdb.h>
#include <nls.h>
// LMBCSから他の文字コードに変換する1文字当たりの最大比率でバッファサイズを計算
#define MAXMESSAGE (MAXSPRINTF * NLS_MAXRATIO_XLATE_FROM_LMBCS)
void test() {
DBHANDLE hDB = NULLHANDLE;
STATUS status = NSFDbOpen("hoge.nsf", &hDB); // 実在しないファイル
if (ERR(status) != NOERROR) {
char lmbcs[MAXSPRINTF + 1];
char buffer[MAXMESSAGE + 1];
WORD len = OSLoadString(NULLHANDLE, ERR(status), lmbcs, MAXSPRINTF);
WORD wlen = OSTranslate(
OS_TRANSLATE_LMBCS_TO_UNICODE, // LMBCSをUNICODE(UTF-16)に変換
lmbcs, len,
buffer, MAXMESSAGE);
std::wstring message(reinterpret_cast<wchar_t*>(buffer), wlen / sizeof(wchar_t));
// message is "ファイルがありません"
}
else {
// Processed correctly.
NSFDbClose(hDB);
}
}
OSLoadStringで返ってくる文字列は、リファレンスによると「LMBCS optimized for Group 1」(言語グループ1に最適化されたLMBCS)であると書かれています。これは、日本語パックを適用したNotes/Dominoを使用していれば、エラー文字列も日本語のLMBCS文字列になるという意味で、改めて翻訳などをする必要がありません。一方でLMBCS文字列であることから、日本語LMBCSは標準出力やUI上にそのまま表示することはできない(必ず文字化けが起きる)ので、必然的に変換処理が必要になってきます。その場合、サンプルコードのようにOSTranslate関数、または(準備が手間ですが)NLS_translate関数で処理できます。
注意: コードの利用においてチブル・システムズは一切の責任を負いません。自己責任でご利用をお願いいたします。