通过 vcpkg 将 HDF5 库加载到 C++ vscode 项目时未解析的外部符号

unresolved external symbol while loading HDF5 library via vcpkg to C++ vscode project

我正在使用 visual studio 项目 2019- 和 vcpkg 以便将数据加载到 CUDA 11.6 C++ visual studio 项目。
在文件的开头我有:

// #define H5_BUILT_AS_DYNAMIC_LIB 
#include <H5Cpp.h>

它没有给出任何错误 - 所以我假设它是由 vcpkg 正确加载和集成的。同样在 post 末尾可见 H5 文件在解决方案资源管理器的外部依赖项列表中可见。

导致错误的简单代码如下所示

    H5::H5File file(FILE_NAME, H5F_ACC_RDONLY);
    H5::DataSet dset = file.openDataSet(DATASET_NAME);

错误(一组未解决的外部符号错误)- 它出现在编译时。

如果我取消注释#define H5_BUILT_AS_DYNAMIC_LIB 1,上面讨论的错误就会消失,但新节目(在运行时)-

hdf5_cpp_D.dll not found ...

完全相同的代码在我的 cmake CUDA C++ 项目上运行良好,但由于各种原因我需要切换到 visual studio 项目。

给出错误的最小示例

#include "cuda_runtime.h"
#include "device_launch_parameters.h"
//#define H5_BUILT_AS_DYNAMIC_LIB 1
#include <H5Cpp.h>
#include <stdio.h>





void loadHDFIntoBoolArr(H5std_string FILE_NAME, H5std_string DATASET_NAME, bool*& data) {


    H5::H5File file(FILE_NAME, H5F_ACC_RDONLY);
    H5::DataSet dset = file.openDataSet(DATASET_NAME);
    /*
     * Get the class of the datatype that is used by the dataset.
     */
    H5T_class_t type_class = dset.getTypeClass();
    H5::DataSpace dspace = dset.getSpace();
    int rank = dspace.getSimpleExtentNdims();


    hsize_t dims[2];
    rank = dspace.getSimpleExtentDims(dims, NULL); // rank = 1
    printf("Datasize: %d \n ", dims[0]); // this is the correct number of values

     // Define the memory dataspace
    hsize_t dimsm[1];
    dimsm[0] = dims[0];
    H5::DataSpace memspace(1, dimsm);

    data = (bool*)calloc(dims[0], sizeof(bool));

    dset.read(data, H5::PredType::NATIVE_HBOOL, memspace, dspace);

    file.close();

}

void loadHDF() {
    const int WIDTH = 512;
    const int HEIGHT = 512;
    const int DEPTH = 826;


    const H5std_string FILE_NAMEonlyLungsBoolFlat("C:\Users\1\PycharmProjects\pythonProject3\mytestfile.hdf5");
    const H5std_string DATASET_NAMEonlyLungsBoolFlat("onlyLungsBoolFlat");
    // create a vector the same size as the dataset
    bool* onlyLungsBoolFlat;
    loadHDFIntoBoolArr(FILE_NAMEonlyLungsBoolFlat, DATASET_NAMEonlyLungsBoolFlat, onlyLungsBoolFlat);

  

}


int main()
{
    loadHDF();
    return 0;
}

使用的 vcpk 命令


.\vcpkg install hdf5
.\vcpkg install hdf5[cpp]
.\vcpkg integrate install

如果您使用定义的 H5_BUILT_AS_DYNAMIC_LIB 1 构建它,则 hdf5_cpp_D.dll 应该位于 vcpkg_installed 目录下的某处。查看 $(vcpkg_root)\installed\ 并搜索 hdf5 目录。那里应该有一个 .\bin 和一个 .\debug\bin 目录以及 hdf5_cpp.dllhdf5_cpp_D.dll。 (我猜 _D 用于调试)。

通常vcpkg integrate install 会设置Visual Studio 以便将vcpkg 目录中的dll 自动复制到您的输出目录。但如果 hdf5 DLL 在运行时动态加载,这可能会失败。您将必须手动复制它(或将路径添加到 PATH 环境变量)。


如果您在未定义 H5_BUILT_AS_DYNAMIC_LIB 1 的情况下构建它,那么这些符号确实应该在静态库 (hdf5.lib) 中定义。在 $(vcpkg)\installed 目录中搜索它们。应该有两个(或四个)不同的,一个用于发布,一个用于调试(每个用于静态与 dll)。

哦,我忘了:你用的是哪个vcpkg triplet?这也可能在 hdf5.lib 链接中发挥作用。

如果您仍然收到链接器错误(未定义的符号),则可能是 hdf5 的 vcpkg 端口不适用于静态链接。你应该用hdf5开票。


我的解决方案很简单,只需重新安装 windows - 在全新安装时,我执行了开始时提到的步骤,现在一切正常