NotesとQtでWindows、Mac OS X、Ubuntuのデスクトップアプリ(その3 - STATUS編)

Notes C APIにおけるSTATUS型は、ほとんどの関数の戻り値となっています。関数の実行結果が成功したのか、失敗したのか、判断する材料となります。

「Notes/Domino APIプログラミング〜」では、std::exceptionを拡張した例外処理として実装しています。私も以前はこれを利用していましたが、Visual C++で例外の仕様が変更され、サンプルをコンパイルすると警告が出るようになりました。それを機に、C++における例外処理について調べてみると、処理の組み方によっては思わぬ処理フローを引き起こす場合があるようで、Notes APIを扱う場合は不向きではないかと考えるようになりました。そこで、STATUS値をラッピングするクラスは、単なるラッパークラスにすることにしました。以下はStatusクラスのヘッダーファイルです。

 

status.h

#ifndef NTLX_STATUS_H
#define NTLX_STATUS_H

#if defined(NT)
#pragma pack(push, 1)
#endif

#include <global.h>

#if defined(NT)
#pragma pack(pop)
#endif

namespace ntlx {

/**
 * @brief The Status class
 */
class Status
{
public:

  /**
   * @brief コンストラクタ
   */
  Status()
  {}

  /**
   * @brief コンストラクタ
   * @param value ステータス値
   */
  Status(STATUS value)
    : value_(value)
  {}

  /**
   * @brief コピーコンストラクタ
   * @param other コピー元
   */
  Status(const Status& other)
    : value_(other.value_)
  {}

  /**
   * @brief 代入演算子
   * @param other 代入元
   * @return 自身への参照
   */
  Status& operator=(const Status& other)
  {
    if (this == &other) return *this;
    value_ = other.value_;
    return *this;
  }

  /**
   * @brief キャスト演算子
   */
  operator STATUS() const { return value_; }

  /**
   * @brief エラー値
   * @return 上位2ピットをマスクしたエラー値
   */
  STATUS error() const { return ERR(value_); }

  /**
   * @brief エラーがないと真を返す
   * @return エラーがなければ真
   */
  bool success() const { return error() == NOERROR; }

  /**
   * @brief エラーがあると真を返す
   * @return エラーがあれば真
   */
  bool failure() const { return !success(); }

  /**
   * @brief すでに表示されていれば真を返す
   * @return 表示済であれば真
   */
  bool hasDisplayed() const { return ((value_ & STS_DISPLAYED) != 0); }

  /**
   * @brief リモート(Dominoサーバ)起因のエラーであれば真を返す
   * @return リモート起因なら真
   */
  bool isRemote() const { return ((value_ & STS_REMOTE) != 0); }

private:
  STATUS value_;
};

}

#endif // NTLX_STATUS_H

 

マルチプラットフォームとして記述するので、Notes APIのヘッダーファイルをインクルードする場合、Windowsにおいては、構造体のアラインメントに配慮する必要があります。最初の方に書かれている#pragma pack(push,1)と#pragma pack(pop)はそのための記述で、これらでAPIヘッダーのインクルード行を挟みます。なお、MacLinuxでは、構造体のアラインメントを考慮する必要はないそうです。

また、WindowsにおいてはWIN32という識別子が定義されるので、これを#ifに使うこともできますが、実はLinuxもこの識別子が必要になります。なので、識別子NTの方が判別しやすいでしょう。(続く)

NotesとQtでWindows、Mac OS X、Ubuntuのデスクトップアプリ(その2 - 共有ライブラリ・作成編)

これからの操作は、基本的にMac OS Xを中心に話を進めます。WindowsUbuntuについては、そのたびに補足していきます。

 

Qt Creatorで、共有ライブラリを作成します。

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

選択ボタンをクリックすると、次に進みます。

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

(画像のエラーはサンプルなので気になさらず)

プロジェクト名はここではntlxとしました。Notes/DominoのAPIについて日本語で書かれた下記の名著に掲載されているライブラリ「NTL」にちなんで付けました。

Notes/Domino APIプログラミング―C++とSTLによる実践的プログラミング

 もちろん、この本やサンプルから多大なる影響を受けています。津田様、この場をお借りして感謝申し上げます。

あとは、使用するQtのバージョンやコンパイラ、使用するQtライブラリ(QtCoreだけで構いません)、初期作成するクラス(Statusとします)、ソースコード管理(Gitなど)を選択すれば、ひな形ができあがります。(続く)

NotesとQtでWindows、Mac OS X、Ubuntuのデスクトップアプリ(その1 - 環境編)

Notes/Dominoは元々クロスプラットフォームグループウェアです。

QtはC++ベースのGUIアプリケーション開発フレームワークで、WindowsMacLinuxなどのプラットフォームで使用できます。

ここでは、この2つを組み合わせてみようという話です。

 

環境をまとめます。

Notesは最新の9.0.1を使います。

Qtは、WindowsMacは5.6、Ubuntuは5.5を使います。

Ubuntuが5.5なのはOSが32bitで、Notesの動作環境としてUbuntu 64bitが含まれないためです。

Windowsは10 64bit、MacはSierra(10.12)、Ubuntuは12.10 32bitです。

コンパイラは、Visual Studioは2013、Xcodeは8.2、gcc/g++は4.6.3です。

 

これらの環境の元、できる限り1つのコードでW-M-Lのいずれでも動作するアプリを作ってみます。

 

今回目標にするのは、NotesのC API Toolkitに含まれるサンプルプログラムのエントリーとなる「basic/intro」「basic/intrwin」 のようなアプリを、Qtベースで作ってみます。この2つは、ユーザから受け取ったサーバ名とパスにあるデータベースから、そのタイトル文字列を取得して返すというものです。

ここで作成するNotes APIに関する実装は、いずれライブラリとして共有していきたいので、メイン+共有ライブラリという構成で構築します。

 

では最初に、Notes C APIにQtをラッピングして、Qt内で使いやすいNotesクラスライブラリを作ってみます。(続く)