10

私は、HDF5 C++ バインディングのいくつかの欠点を回避する方法を考え出そうとしています。現在、私のコードには、次のような try/catch ブロックが散らばっています。

H5::Exception::dontPrint();
H5::H5File *file = NULL;
try {
    file = new H5::H5File(fname.c_str(), H5F_ACC_RDWR);
} catch(H5::FileIException &file_exists_err) {
    file = new H5::H5File(fname.c_str(), H5F_ACC_TRUNC);
}

これは必要ないはずです。やりたいことは、読み取り/書き込みアクセス用にファイルを開き、存在しない場合は作成することだけです。もう 1 つの厄介な問題は、親グループが必ずしも存在しないネストされたグループ (例: "/parent/group") を作成することです。Unix/Linux では、同等のものは次のようになります。

mkdir -p parent/group

ただし、HDF5 C++ バインディングでは、親グループが存在しないグループを作成すると、例外が発生します。

これらの理由から、これらの一般的な問題のいくつかを扱うヘッダー ファイルを作成することにしました。私が最初に考えたのは、たとえば、ファイル名とアクセス モードを取得して H5::H5File オブジェクトを返す関数、またはグループ名を取得してグループ オブジェクトを返す関数のセットを単純に作成することでした。ただし、プログラマーが自分のコードで明示的に「new」を呼び出すことは決してないにもかかわらず、このヘッダー ファイルを使用して返されたオブジェクトで「delete」を呼び出すプログラマーを残すため、これは理想的ではないと思います。これはメモリリークを求めているようです。

したがって、私の 2 番目の考えは、H5::H5File と H5::H5Group から一連の派生クラスを作成し、ファイルがまだ存在しない場合、またはグループの親グループがまだ存在しない場合に例外をスローしないコンストラクターを作成することでした。 . 派生ファイル クラスに対する私の試みは次のとおりです。

namespace H5Utils {

class H5File : public H5::H5File {
public:
    H5File(std::string fname);
    ~H5File();
};

}

H5Utils::H5File::H5File(std::string fname)
try : H5::H5File(fname.c_str(), H5F_ACC_RDWR)
{
    std::cerr << "Opened existing file." << std::endl;
} catch(H5::FileIException &file_exists_err) {
    std::cerr << "File does not exist. Creating new file." << std::endl;
    H5::H5File(fname.c_str(), H5F_ACC_TRUNC);
}

H5Utils::H5File::~H5File() { }

私が直面している問題は 2 つあります。まず、コンストラクターの try/catch ブロックが、によって作成された例外を再スローします。

H5::H5File(fname.c_str(), H5F_ACC_RDWR)

ファイルが存在しない場合、プログラムは引き続き終了します。2 番目の問題は、2 番目のコンストラクターが

H5::H5File(fname.c_str(), H5F_ACC_TRUNC);

正しいです (つまり、親クラスを構築しますか?) 派生クラスが基本クラスのコンストラクターで例外をキャッチし、基本クラスの別のコンストラクターを呼び出す方法はありますか?

より一般的には、HDF5 C++ バインディングのこれらの欠点に対処するためのより良い/よりエレガントな方法を考えられる人はいますか?

4

2 に答える 2

7

いくつかの単純なヘルパー関数を作成するという最初のアイデアを好みます-それはより単純になり、記述して文書化する必要があるコードの量を最小限に抑えます。さらに、適切なメモリ管理を確保するために、shared_ptr.

最初の例に相当する単純なラッパー関数を次に示します。

// a typedef for our managed H5File pointer
typedef std::shared_ptr<H5::H5File> H5FilePtr;

// create or open a file
H5FilePtr create_or_open(const std::string& fname)
{
    H5::Exception::dontPrint();
    H5::H5File* file = 0;

    try {
        file = new H5::H5File(fname.c_str(), H5F_ACC_RDWR);
    } catch(const H5::FileIException&) {
        file = new H5::H5File(fname.c_str(), H5F_ACC_TRUNC);
    }

    return H5FilePtr(file);
}
于 2012-12-12T22:41:05.300 に答える
4

ただし、HDF5 C++ バインディングでは、親グループが存在しないグループを作成すると、例外が発生します。

リンク作成プロパティ リストを設定して、不足している中間グループを作成し、この例外を回避できます。例えば:

#include "hdf5.h"

int main (void){
  hid_t lcpl, file_id, group_id;
  herr_t status;
  unsigned flag=1;

  lcpl = H5Pcreate(H5P_LINK_CREATE);
  status = H5Pset_create_intermediate_group(lcpl, flag);
  file_id = H5Fcreate("nested_groups.h5",  H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
  group_id = H5Gcreate( file_id, "/foo/bar/bop", lcpl, H5P_DEFAULT, H5P_DEFAULT );

  H5Pclose(lcpl);
  H5Gclose(group_id);
  H5Fclose(file_id);

  return status;
}
于 2016-06-15T22:34:40.277 に答える