C\C++ 写 HDF5 文件示例

C\C++ 写 HDF5 文件示例

  • 一. 背景
  • 二. 需要的头文件和库文件
  • 三. VS2012工程示例
  • 四. 各种坑
  • 五. 运行代码
  • 六. C++版本
  • 七. 代码下载

一. 背景

TensorFlow 或者 Keras 保存的 Model 或者 Weight 都是 HDF5 文件, 当我们想用 C++ 实现加载 Model 或者 Weight 的时候, 就需要操作 HDF5 文件, 所以在这里做一个写 HDF5 文件的例子, 给大家参考一下

二. 需要的头文件和库文件

这个可以从网上下载自己编译, 但是 1.10.6 版本会缺少头文件 H5pubconf.h, 可参考 HDF5 CMake 生成 C\C++ 可用的 lib 文件和 dll 文件 或者直接下载我编译好的(包含 H5pubconf.h),
下载地址: C\C++ 读写 HDF5 所需头文件和库文件

三. VS2012工程示例

  1. 新建一个 Win32 控制台应用程序, 我起名为 HDF5, 名称你起你喜欢的就好
#include "stdafx.h"

int _tmain(int argc, _TCHAR* argv[])
{
	return 0;
}
  1. 添加包含目录和库目录
    把生成或者下载好的文件放到你喜欢的地方就好, 这里我放到了 D 盘, 如下图
    C\C++ 写 HDF5 文件示例_第1张图片
  2. 添加头文件
#include "stdafx.h"
#include  // 需要添加的头文件

int _tmain(int argc, _TCHAR* argv[])
{
	return 0;
}

添加完成之后, 会显示找不到头文件, 如下图, 没有关系, 因为我们还没有添加包含目录
no file
4. 设置包含目录
包含目录设置完成之后, include 那一行就不会画红线了
C\C++ 写 HDF5 文件示例_第2张图片
6. 设置库目录
C\C++ 写 HDF5 文件示例_第3张图片
经过上面的设置之后, 基本就完成了, 下面开始填坑

四. 各种坑

  1. 坑 1:
    上面的步骤完成之后, 直接生成解决方案, 会看到下面的错误C\C++ 写 HDF5 文件示例_第4张图片
    我们什么都没有写, 怎么会有错误呢? 是因为 h5fdhdfs.h 这个文件中的用到 int32_t 这样的数据类型, 而这个数据类型包含在了
    stdint.h 这个头文件中, 所以我们只需要在 #include 的前面加上 #include 就好了
    C\C++ 写 HDF5 文件示例_第5张图片
  2. 坑 2:
    现在总要写一点东西出来实验一下对不对, 我们就把源代码里面的 Sample 复制出来看一下能不能行, 源代码里面有一个写文件的例子(hdf5-1.10.6\examples\h5_write.c), 将其复制如下
#include "stdafx.h"

#include 
#include 

#define H5FILE_NAME "SDS.h5"
#define DATASETNAME "IntArray"
#define NX		5	/* dataset dimensions */
#define NY      6
#define RANK    2

int _tmain(int argc, _TCHAR* argv[])
{
	hid_t       file, dataset;         /* file and dataset handles */
    hid_t       datatype, dataspace;   /* handles */
    hsize_t     dimsf[2];              /* dataset dimensions */
    herr_t      status;
    int         data[NX][NY];          /* data to write */
    int         i, j;

    /*
     * Data  and output buffer initialization.
     */
    for(j = 0; j < NX; j++)
	{
		for(i = 0; i < NY; i++)
	    {
			data[j][i] = i + j;
		}
	}

    /*
     * 0 1 2 3 4 5
     * 1 2 3 4 5 6
     * 2 3 4 5 6 7
     * 3 4 5 6 7 8
     * 4 5 6 7 8 9
     */

    /*
     * Create a new file using H5F_ACC_TRUNC access,
     * default file creation properties, and default file
     * access properties.
     */
    file = H5Fcreate(H5FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);

    /*
     * Describe the size of the array and create the data space for fixed
     * size dataset.
     */
    dimsf[0] = NX;
    dimsf[1] = NY;
    dataspace = H5Screate_simple(RANK, dimsf, NULL);

    /*
     * Define datatype for the data in the file.
     * We will store little endian INT numbers.
     */
    datatype = H5Tcopy(H5T_NATIVE_INT);
    status = H5Tset_order(datatype, H5T_ORDER_LE);

    /*
     * Create a new dataset within the file using defined dataspace and
     * datatype and default dataset creation properties.
     */
    dataset = H5Dcreate2(file, DATASETNAME, datatype, dataspace,
			H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);

    /*
     * Write the data to the dataset using default transfer properties.
     */
    status = H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, data);

    /*
     * Close/release resources.
     */
    H5Sclose(dataspace);
    H5Tclose(datatype);
    H5Dclose(dataset);
    H5Fclose(file);

	return 0;
}

先不管是什么意思, 生成解决方案看一下, 结果一生成, 整个人都不好了, 报了一堆错误

C\C++ 写 HDF5 文件示例_第6张图片
遇到 error LNK2019: 无法解析的外部符号 这样的错误, 作为一个 C++ 程序猿, 相信你已经遇到过千百次了, 意思就是找不到 lib 文件嘛, 那我们就把相关的 lib 文件(这里只需要 hdf5_D.lib, 带 D 表示调试版本)添加到 附加依赖项 里面

C\C++ 写 HDF5 文件示例_第7张图片

如果你不喜欢附加依赖项这样的方式, 你用以下的方式, 一样的效果

#include 
#include 

#ifdef _DEBUG
#pragma comment(lib, "hdf5_D.lib")
#else
#pragma comment(lib, "hdf5.lib")
#endif

最下面还有一个错误是 fatal error LNK1120: 1 个无法解析的外部命令, 这个要怎么解? 只需要增加一个预处理器定义H5_BUILT_AS_DYNAMIC_LIB 就好了

C\C++ 写 HDF5 文件示例_第8张图片
现在再来生成看一下, 已经没有问题了

五. 运行代码

按 F5 运行看一下, 马上又有错误

C\C++ 写 HDF5 文件示例_第9张图片

这个问题很简单, 相信你也遇到过千百回了, 只需要将编译好的 dll 或者下载的 bin 目录中的 dll 复制到你的工程目录中的 Debug 或者 Release 文件夹下就可以了, 如果是调试就是 Debug, 不用全都复制, 因为现在只需要 hdf5_D.dll, 也可以将 hdf5_D.dll 所在目录添加到添加环境变量, 不过复制方便一点

完成后再运行, 就不会报错了, 黑色窗口一闪而过, 在工程目录下留下一个 SDS.h5 文件
C\C++ 写 HDF5 文件示例_第10张图片
C\C++ 写 HDF5 文件示例_第11张图片
现在你可以用 HDF5 View 之类的看一下里面写的是什么了, 打开之后就是代码里面写的那个二维数组
注意, HDF5 View 不能打开有中文路径的文件

C\C++ 写 HDF5 文件示例_第12张图片

具体代码中的每个函数是什么意思, 自己也能推敲出来吧, 或者到官网转一下

六. C++版本

以上是 C语言版本的示例, C++版本示例可以在 hdf5-1.10.6\c++\examples 找到, 只是要注意附加依赖项要多一个
hdf5_cpp_D.lib 或者 hdf5_cpp.lib

七. 代码下载

完整的代码可下载 VS2015 x64 代码示例

你可能感兴趣的:(HDF5,HDF5,C++)