经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C++ » 查看文章
使用C/C++读写.mat文件的方法详解
来源:jb51  时间:2022/3/8 10:43:42  对本文有异议

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

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

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

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

  1. #include <cstdio>
  2. #include "mat.h"
  3. const char *path = "D:\\Codes\\MATLAB\\test.mat";
  4. int diagnose(const char *file) {
  5. MATFile *pmat;
  6. const char **dir;
  7. const char *name;
  8. int ndir;
  9. int i;
  10. mxArray *pa;
  11. printf("Reading file %s...\n\n", file);
  12. /*
  13. * Open file to get directory
  14. */
  15. pmat = matOpen(file, "r");
  16. if (pmat == NULL) {
  17. printf("Error opening file %s\n", file);
  18. return (1);
  19. }
  20. /*
  21. * get directory of MAT-file
  22. */
  23. dir = (const char **) matGetDir(pmat, &ndir);
  24. if (dir == NULL) {
  25. printf("Error reading directory of file %s\n", file);
  26. return (1);
  27. } else {
  28. printf("Directory of %s:\n", file);
  29. for (i = 0; i < ndir; i++)
  30. printf("%s\n", dir[i]);
  31. }
  32. mxFree(dir);
  33. /* In order to use matGetNextXXX correctly, reopen file to read in headers. */
  34. if (matClose(pmat) != 0) {
  35. printf("Error closing file %s\n", file);
  36. return (1);
  37. }
  38. pmat = matOpen(file, "r");
  39. if (pmat == NULL) {
  40. printf("Error reopening file %s\n", file);
  41. return (1);
  42. }
  43. /* Get headers of all variables */
  44. printf("\nExamining the header for each variable:\n");
  45. for (i = 0; i < ndir; i++) {
  46. pa = matGetNextVariableInfo(pmat, &name);
  47. if (pa == NULL) {
  48. printf("Error reading in file %s\n", file);
  49. return (1);
  50. }
  51. /* Diagnose header pa */
  52. printf("According to its header, array %s has %d dimensions\n",
  53. name, mxGetNumberOfDimensions(pa));
  54. if (mxIsFromGlobalWS(pa))
  55. printf(" and was a global variable when saved\n");
  56. else
  57. printf(" and was a local variable when saved\n");
  58. mxDestroyArray(pa);
  59. }
  60. /* Reopen file to read in actual arrays. */
  61. if (matClose(pmat) != 0) {
  62. printf("Error closing file %s\n", file);
  63. return (1);
  64. }
  65. pmat = matOpen(file, "r");
  66. if (pmat == NULL) {
  67. printf("Error reopening file %s\n", file);
  68. return (1);
  69. }
  70. /* Read in each array. */
  71. printf("\nReading in the actual array contents:\n");
  72. for (i = 0; i < ndir; i++) {
  73. pa = matGetNextVariable(pmat, &name);
  74. if (pa == NULL) {
  75. printf("Error reading in file %s\n", file);
  76. return (1);
  77. }
  78. /*
  79. * Diagnose array pa
  80. */
  81. printf("According to its contents, array %s has %d dimensions\n",
  82. name, mxGetNumberOfDimensions(pa));
  83. if (mxIsFromGlobalWS(pa))
  84. printf(" and was a global variable when saved\n");
  85. else
  86. printf(" and was a local variable when saved\n");
  87. mxDestroyArray(pa);
  88. }
  89. if (matClose(pmat) != 0) {
  90. printf("Error closing file %s\n", file);
  91. return (1);
  92. }
  93. printf("Done\n");
  94. return (0);
  95. }
  96. int main() {
  97. int result;
  98. result = diagnose(path);
  99. if (!result) {
  100. printf("SUCCESS!\n");
  101. } else {
  102. printf("FALURE!\n");
  103. }
  104. return 0;
  105. }

二、修改CmakeLists文件

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

  1. set(INC_DIR1 E:\\MATLAB\\R2019b\\extern\\include)
  2. set(INC_DIR2 E:\\MATLAB\\R2019b\\extern\\include\\win64)
  3. # head file path,头文件目录
  4. include_directories(${INC_DIR1}) # 指定头文件的搜索路径,相当于指定 gcc 的 - I 参数
  5. include_directories(${INC_DIR2}) # 指定头文件的搜索路径,相当于指定 gcc 的 - I 参数

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

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

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

  1. cmake_minimum_required(VERSION 3.21)
  2. # project name,指定项目的名称,一般和项目的文件夹名称对应
  3. project(read_mat)
  4. # 设置参数
  5. set(CMAKE_CXX_STANDARD 14)
  6. set(INC_DIR1 E:\\MATLAB\\R2019b\\extern\\include)
  7. set(INC_DIR2 E:\\MATLAB\\R2019b\\extern\\include\\win64)
  8. set(LINK_DIR E:\\MATLAB\\R2019b\\extern\\lib\\win64\\mingw64)
  9. # head file path,头文件目录
  10. include_directories(${INC_DIR1}) # 指定头文件的搜索路径,相当于指定 gcc 的 - I 参数
  11. include_directories(${INC_DIR2}) # 指定头文件的搜索路径,相当于指定 gcc 的 - I 参数
  12. link_directories(${LINK_DIR}) # 动态链接库或静态链接库的搜索路径,相当于 gcc 的 - L 参数
  13. link_libraries(libmat libmx libmex libeng) # All targets link with the same set of libs
  14. cmake_minimum_required(VERSION 3.21)
  15. add_executable(read_mat main.cpp)

三、添加环境变量

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

  1. E:\MATLAB\R2019b\bin\win64
  2. E:\MATLAB\R2019b\extern\lib\win64\mingw64

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

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

  1. Process finished with exit code -1073741515 (0xC0000135)

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

四、令人头秃的错误

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

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

image-20220306181441883

出现这种问题的原因是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

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注w3xue的更多内容!  

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号