使用C/C++讀寫.mat文件的方法詳解
最近需要使用C++來處理matlab生成的數(shù)據(jù), 參考了網(wǎng)上一些博客,不過他們都是使用的VS,我比較喜歡使用Clion, 在配置的過程中也遇到了一些坑,記錄一下。
一、創(chuàng)建工程并添加測試代碼
創(chuàng)建工程就不說了,注意一下我使用的編譯工具鏈是MinGW。測試代碼參考的matlab官方的程序:讀取用 C/C++ 編寫的 MAT 文件 - MATLAB & Simulink - MathWorks 中國,對官方的代碼進行了小小的調(diào)整。
將程序中的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文件
設(shè)置包含路徑(相當于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 參數(shù) include_directories(${INC_DIR2}) # 指定頭文件的搜索路徑,相當于指定 gcc 的 - I 參數(shù)
設(shè)置庫目錄(相當于VS中的添加附加庫目錄),以及需要包含的庫(相當于VS中的添加附加依賴庫):
set(LINK_DIR E:\\MATLAB\\R2019b\\extern\\lib\\win64\\mingw64 link_directories(${LINK_DIR}) # 動態(tài)鏈接庫或靜態(tài)鏈接庫的搜索路徑,相當于 gcc 的 - L 參數(shù) link_libraries(libmat libmx libmex libeng) # All targets link with the same set of libs
下面是我的CmakeLists
文件的完整內(nèi)容:
cmake_minimum_required(VERSION 3.21) # project name,指定項目的名稱,一般和項目的文件夾名稱對應 project(read_mat) # 設(shè)置參數(shù) 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 參數(shù) include_directories(${INC_DIR2}) # 指定頭文件的搜索路徑,相當于指定 gcc 的 - I 參數(shù) link_directories(${LINK_DIR}) # 動態(tài)鏈接庫或靜態(tài)鏈接庫的搜索路徑,相當于 gcc 的 - L 參數(shù) 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)
三、添加環(huán)境變量
添加下面的環(huán)境變量,注意替換matlab安裝地址。
E:\MATLAB\R2019b\bin\win64 E:\MATLAB\R2019b\extern\lib\win64\mingw64
記得添加完環(huán)境變量后重啟一下電腦。
重啟完成后,對于部分人來說到這里整個配置就完成了,就能夠運行程序了。但是部分人比如說我自己,在運行的時候出現(xiàn)下面的錯誤:
Process finished with exit code -1073741515 (0xC0000135)
如果遇到這樣的錯誤,請繼續(xù)往下面看。
四、令人頭禿的錯誤
對于上面的錯誤,我嘗試了在網(wǎng)上搜索,可是沒有找到解決的辦法。然后我就使用VS配置了一遍,程序運行還是失敗了,提示遇到了如下的錯誤:
無法定位程序輸入點H5Rdereference于動態(tài)鏈接庫libmat.dll上
出現(xiàn)這種問題的原因是dll動態(tài)庫發(fā)生了沖突,我是因為添加了Anaconda的環(huán)境變量,在Anaconda中也有hdf5.dll
文件,程序首先定位到了Anaconda的dll文件,而不是matlab的dll文件,解決沖突的辦法就是將Anacomda的環(huán)境變量移動到matlab環(huán)境變量之后即可。
記得修改完環(huán)境變量之后重啟一下電腦。
五、運行結(jié)果
解決完前面遇到的問題后,再次運行程序,可以看到成功了,程序輸出結(jié)果如下:
Directory of D:\Codes\MATLAB\DP-TBD\matlab_code\test.mat:
matrixExamining the header for each variable:
According to its header, array matrix has 2 dimensions
and was a local variable when savedReading 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
總結(jié)
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
c語言 數(shù)據(jù)結(jié)構(gòu)實現(xiàn)之字符串
這篇文章主要介紹了c語言 數(shù)據(jù)結(jié)構(gòu)實現(xiàn)之字符串的相關(guān)資料,需要的朋友可以參考下2017-05-05