使用C/C++读写.mat文件(Clion)

使用C/C++读写.mat文件(Clion)

最近需要使用C++来处理matlab生成的数据, 参考了网上一些博客,不过他们都是使用的VS,我比较喜欢使用Clion, 在配置的过程中也遇到了一些坑,记录一下。

一、创建工程并添加测试代码

创建工程就不说了,注意一下我使用的编译工具链是MinGW。测试代码参考的matlab官方的程序:读取用 C/C++ 编写的 MAT 文件 - MATLAB & Simulink - MathWorks 中国,对官方的代码进行了小小的调整。

将程序中的path替换为你的mat文件所在完整地址即可。

#include <cstdio>
#include "mat.h"

const char *path = "D:\\Codes\\MATLAB\\test.mat";

int diagnose(const char *file) {
    MATFile *pmat;
    const char **dir;
    const char *name;
    int ndir;
    int i;
    mxArray *pa;

    printf("Reading file %s...\n\n", file);

    /*
     * Open file to get directory
     */
    pmat = matOpen(file, "r");
    if (pmat == NULL) {
        printf("Error opening file %s\n", file);
        return (1);
    }

    /*
     * get directory of MAT-file
     */
    dir = (const char **) matGetDir(pmat, &ndir);
    if (dir == NULL) {
        printf("Error reading directory of file %s\n", file);
        return (1);
    } else {
        printf("Directory of %s:\n", file);
        for (i = 0; i < ndir; i++)
            printf("%s\n", dir[i]);
    }
    mxFree(dir);

    /* In order to use matGetNextXXX correctly, reopen file to read in headers. */
    if (matClose(pmat) != 0) {
        printf("Error closing file %s\n", file);
        return (1);
    }
    pmat = matOpen(file, "r");
    if (pmat == NULL) {
        printf("Error reopening file %s\n", file);
        return (1);
    }

    /* Get headers of all variables */
    printf("\nExamining the header for each variable:\n");
    for (i = 0; i < ndir; i++) {
        pa = matGetNextVariableInfo(pmat, &name);
        if (pa == NULL) {
            printf("Error reading in file %s\n", file);
            return (1);
        }
        /* Diagnose header pa */
        printf("According to its header, array %s has %d dimensions\n",
               name, mxGetNumberOfDimensions(pa));
        if (mxIsFromGlobalWS(pa))
            printf("  and was a global variable when saved\n");
        else
            printf("  and was a local variable when saved\n");
        mxDestroyArray(pa);
    }

    /* Reopen file to read in actual arrays. */
    if (matClose(pmat) != 0) {
        printf("Error closing file %s\n", file);
        return (1);
    }
    pmat = matOpen(file, "r");
    if (pmat == NULL) {
        printf("Error reopening file %s\n", file);
        return (1);
    }

    /* Read in each array. */
    printf("\nReading in the actual array contents:\n");
    for (i = 0; i < ndir; i++) {
        pa = matGetNextVariable(pmat, &name);
        if (pa == NULL) {
            printf("Error reading in file %s\n", file);
            return (1);
        }
        /*
         * Diagnose array pa
         */
        printf("According to its contents, array %s has %d dimensions\n",
               name, mxGetNumberOfDimensions(pa));
        if (mxIsFromGlobalWS(pa))
            printf("  and was a global variable when saved\n");
        else
            printf("  and was a local variable when saved\n");
        mxDestroyArray(pa);
    }

    if (matClose(pmat) != 0) {
        printf("Error closing file %s\n", file);
        return (1);
    }
    printf("Done\n");
    return (0);
}

int main() {

    int result;

    result = diagnose(path);

    if (!result) {
        printf("SUCCESS!\n");
    } else {
        printf("FALURE!\n");
    }

    return 0;
}

二、修改CmakeLists文件

设置包含路径(相当于VS中的添加附加包含目录):

set(INC_DIR1 E:\\MATLAB\\R2019b\\extern\\include)
set(INC_DIR2 E:\\MATLAB\\R2019b\\extern\\include\\win64)

# head file path,头文件目录
include_directories(${INC_DIR1}) # 指定头文件的搜索路径,相当于指定 gcc 的 - I 参数
include_directories(${INC_DIR2}) # 指定头文件的搜索路径,相当于指定 gcc 的 - I 参数

设置库目录(相当于VS中的添加附加库目录),以及需要包含的库(相当于VS中的添加附加依赖库):

set(LINK_DIR E:\\MATLAB\\R2019b\\extern\\lib\\win64\\mingw64
link_directories(${LINK_DIR}) # 动态链接库或静态链接库的搜索路径,相当于 gcc 的 - L 参数
link_libraries(libmat libmx libmex libeng) # All targets link with the same set of libs

下面是我的CmakeLists文件的完整内容:

cmake_minimum_required(VERSION 3.21)
# project name,指定项目的名称,一般和项目的文件夹名称对应
project(read_mat)

# 设置参数
set(CMAKE_CXX_STANDARD 14)

set(INC_DIR1 E:\\MATLAB\\R2019b\\extern\\include)
set(INC_DIR2 E:\\MATLAB\\R2019b\\extern\\include\\win64)

set(LINK_DIR E:\\MATLAB\\R2019b\\extern\\lib\\win64\\mingw64)

# head file path,头文件目录
include_directories(${INC_DIR1}) # 指定头文件的搜索路径,相当于指定 gcc 的 - I 参数
include_directories(${INC_DIR2}) # 指定头文件的搜索路径,相当于指定 gcc 的 - I 参数

link_directories(${LINK_DIR}) # 动态链接库或静态链接库的搜索路径,相当于 gcc 的 - L 参数

link_libraries(libmat libmx libmex libeng) # All targets link with the same set of libs

cmake_minimum_required(VERSION 3.21)

add_executable(read_mat main.cpp)

三、添加环境变量

添加下面的环境变量,注意替换matlab安装地址。

E:\MATLAB\R2019b\bin\win64
E:\MATLAB\R2019b\extern\lib\win64\mingw64

记得添加完环境变量后重启一下电脑。

重启完成后,对于部分人来说到这里整个配置就完成了,就能够运行程序了。但是部分人比如说我自己,在运行的时候出现下面的错误:

Process finished with exit code -1073741515 (0xC0000135)

如果遇到这样的错误,请继续往下面看。

四、令人头秃的错误

对于上面的错误,我尝试了在网上搜索,可是没有找到解决的办法。然后我就使用VS配置了一遍,程序运行还是失败了,提示遇到了如下的错误:

无法定位程序输入点H5Rdereference于动态链接库libmat.dll上

image-20220306181441883

然后我在一位大佬的博客中找到了问题的解决方法,大家可以看这位博主的原文,无法定位程序输入点H5Rdereference于动态链接库 libmat.dll上_sinat_36156541的博客-CSDN博客,出现这种问题的原因是dll动态库发生了冲突,我是因为添加了Anaconda的环境变量,在Anaconda中也有hdf5.dll文件,程序首先定位到了Anaconda的dll文件,而不是matlab的dll文件,解决冲突的办法就是将Anacomda的环境变量移动到matlab环境变量之后即可。

记得修改完环境变量之后重启一下电脑。

五、运行结果

解决完前面遇到的问题后,再次运行程序,可以看到成功了,程序输出结果如下:

Directory of D:\Codes\MATLAB\DP-TBD\matlab_code\test.mat:
matrix

Examining the header for each variable:
According to its header, array matrix has 2 dimensions
  and was a local variable when saved

Reading in the actual array contents:
According to its contents, array matrix has 2 dimensions
  and was a local variable when saved
Done
SUCCESS!

Process finished with exit code 0

image-20220306182216916

参考

C++读写.mat文件_JimYe的专栏-CSDN博客_matopen

【C++、Matlab】VS2013 C++读写.mat文件_不用先生的博客-CSDN博客_matopen

读取用 C/C++ 编写的 MAT 文件 - MATLAB & Simulink - MathWorks 中国

无法定位程序输入点H5Rdereference于动态链接库 libmat.dll上_sinat_36156541的博客-CSDN博客

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
CMake Error at /Users/fym/Library/Application Support/JetBrains/Toolbox/apps/CLion/ch-0/232.8453.115/CLion 2023.2 EAP.app/Contents/bin/cmake/mac/share/cmake-3.26/Modules/CMakeTestCXXCompiler.cmake:60 (message): The C++ compiler "/usr/local/bin/g++-13" is not able to compile a simple test program. It fails with the following output: Change Dir: /Users/fym/Desktop/C++/cmake-build-debug/CMakeFiles/CMakeScratch/TryCompile-FQ7Av9 Run Build Command(s):/Users/fym/Library/Application Support/JetBrains/Toolbox/apps/CLion/ch-0/232.8453.115/CLion 2023.2 EAP.app/Contents/bin/ninja/mac/ninja -v cmTC_c8b71 && [1/2] /usr/local/bin/g++-13 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX13.3.sdk -fdiagnostics-color=always -o CMakeFiles/cmTC_c8b71.dir/testCXXCompiler.cxx.o -c /Users/fym/Desktop/C++/cmake-build-debug/CMakeFiles/CMakeScratch/TryCompile-FQ7Av9/testCXXCompiler.cxx [2/2] : && /usr/local/bin/g++-13 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX13.3.sdk -Wl,-search_paths_first -Wl,-headerpad_max_install_names CMakeFiles/cmTC_c8b71.dir/testCXXCompiler.cxx.o -o cmTC_c8b71 && : FAILED: cmTC_c8b71 : && /usr/local/bin/g++-13 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX13.3.sdk -Wl,-search_paths_first -Wl,-headerpad_max_install_names CMakeFiles/cmTC_c8b71.dir/testCXXCompiler.cxx.o -o cmTC_c8b71 && : ld: unsupported tapi file type '!tapi-tbd' in YAML file '/Library/Developer/CommandLineTools/SDKs/MacOSX13.3.sdk/usr/lib/libSystem.tbd' for architecture x86_64 collect2: error: ld returned 1 exit status ninja: build stopped: subcommand failed. CMake will not be able to correctly generate this project. Call Stack (most recent call first): CMakeLists.txt:2 (project) -- Configuring incomplete, errors occurred!
07-11

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值