C++调用MATLAB函数
MATLAB具有著很高的計算性能,一些算法用MATLAB很容易實現,而用C++很難實現,如果想在C++中調用MATLAB編寫的函數,可以將該函數編譯成庫文件,之后在C++中對其進行調用。
本文詳細講解如何將MATLAB函數編譯成庫,并在C++中進行調用。方法可行,本人親測。
第一步、在MATLAB中的命令行窗口中輸入mex -setup,會出現如下界面。
第二步、點擊界面中的“mex -setup C++”,出現如下提示。
第三步、之后就是進行對MATLAB中的function的編譯了。這里,我的函數名為phasecong,實現的是圖像相位一致性的計算。如下圖所示。
這個函數是一位大牛學者寫的,原本是有多個輸入和多個輸出的,但是為了編譯方便和后續調用方便,我把其他幾個參數刪掉了,只保留了一個輸入矩陣和一個輸出矩陣。
這樣做的好處是可以減少編譯和調用出錯的概率。編譯方法見第四步。
第四步、下面就是對function進行編譯了,編譯的命令為:mcc -W cpplib:pc -T link:lib phasecong
這條命令中pc表示的是想要生成的庫的名稱,可以自己定,最后面的phasecong表示的是要編譯的函數的名,注意函數名后面不要加.m后綴。其他的參數都不用改。
如下圖所示。
第五步、輸入完上面的命令后就是等待MATLAB編譯完成了,我當時編譯好像用了30秒左右的時間。
編譯完成后就會出現編譯成功的提示,如下圖所示。
需要注意的是,在編譯時,當前文件夾一定要為function所在的文件夾。
第六步、經過上面的編譯后,在該文件夾下就會生成.h .cpp .lib .dll這四個文件,因為我設置的輸出的庫名稱為pc,因此我這里生成pc.h pc.cpp pc.lib pc.dll這四個文件。
第七步、接下來就是將生成的這四個文件加入到我們的C++工程中了。
將這四個文件放在C++工程的文件夾中,最好在該文件夾中新建兩個文件夾,分別命名為lib和include,因為后面我們還需要引入其他的庫文件和頭文件,這樣做可以讓文件更整齊。然后將pc.lib放入lib文件夾,將pc.h放入include文件夾。然后在VS中右鍵項目,點擊屬性,在屬性中選擇“配置屬性”->“VC++目錄”->“包含目錄”,將剛才建立的include文件夾包含進去,如下圖所示。其他的屬性都不用改。
這樣我們就將頭文件包含了進去,之后進行加載lib文件,這里我們使用靜態加載方式,在工程文件中加入這樣一條語句:
#pragma comment(lib, ".\\lib\\pc.lib" )對于pc.dll和pc.cpp文件,值需要將其放在工程目錄下就可以,不用進行配置。
這樣就完成了對這四個文件的配置。
第八步、配置好生成的這四個文件后就可以運行C++的程序了,但是點擊運行后應該會報錯(通常一定會報錯),不要怕,這是因為我們前面生成的這四個文件是需要依賴其他的庫和頭文件才能工作的。我們根據報錯的信息可以知道缺少的頭文件,例如下圖這個錯誤:
通過這個錯誤我們就可以知道,我們的項目中缺少mat.h這個頭文件,這時我們就要找到這個頭文件并將其加入到include文件夾中。到哪里去找呢,在這個文件夾中“D:\Program Files\MATLAB\R2014b\extern\include”。重復這一操作,直到不再提示這種錯誤。這一操作需要重復很多次,像我這個項目需要加入下圖這么多的頭文件。
之后還需要加入額外的lib庫文件,具體加入哪些lib文件,需要根據上面的這些頭文件而定,我們到文件夾“D:\Program Files\MATLAB\R2014b\extern\lib\win64\microsoft”中(因為我的MATLAB是64位的,所以在win64文件夾下,如果大家的MATLAB是32位的,那么估計是在win32文件夾下,大家自己找一下),尋找上面這些頭文件同名的lib文件,不過并不是每個頭文件都能找到同名的lib文件,不過不要緊,我們只要把能找到的lib文件復制到工程目錄下的lib文件夾中即可,除了這些lib文件之外,還需要加上“libmat.lib”和“libmx.lib”這兩個文件,這兩個文件好像包括著必要的類型的定義之類的吧。搞定之后我的lib文件夾中有下圖這些個文件。
這些lib的加載方式與之前我們說的pc.lib的加載方式相同,如下圖所示。
進行到此,我們所有的配置就都搞定了,如果沒有意外的話,C++的項目編譯就可以通過了,
但是雖然編譯通過了,在運行的過程中還是有可能提示缺少某個庫文件,我們只需要采用同樣的方法把那些庫文件加到項目里即可,比如我這個程序還提示我缺少mclmcr.dll這個文件,我就把這個文件復制到工程目錄下就可以了,所需的dll文件通常都在“D:\Program Files\MATLAB\R2014b\bin\win64”這個文件夾可以找到。
至此我們就完成了MATLAB函數的編譯和C++調用的整個過程。
最后是幾點提示:
1、我這里使用的是MATLAB2014a和vs2013。
2、如果使用的MATLAB是64位的版本,那么C++的程序也要在x64下配置!!!!!!!
??????如果使用的MATLAB是32位的版本,那么C++的程序也要在win32下配置!!!!!!
??????這點非常重要!!!!!!!!
3、MATLAB函數的輸入和輸出參數通常都是矩陣,在C++中矩陣變量使用mwArray這個類型,這個類的使用方法可以看我下面貼的代碼,也可以在網上找教程。
4、在C++程序中,我們調用這個函數的名稱與MATLAB中定義的函數名稱相同,這個函數是在MATLAB編譯后生成的頭文件中進行的聲明,例如我這里是在pc.h中。
5、在C++程序中,在定義輸入數組和輸出數組時,最好使用動態數組,因為傳統的數組是在棧中分配內存,這樣會造成內存溢出。
最后為了更直觀的展示在C++中如何對這些個庫文件進行的調用以及如何使用這個函數,我在這里貼上了C++程序的源代碼。
// pcproj.cpp : 定義控制臺應用程序的入口點。 //#include "stdafx.h" #include "pc.h" #include <iostream> #include <fstream>using namespace std;?#pragma comment(lib, ".\\lib\\pc.lib" ) #pragma comment(lib, ".\\lib\\mclmcrrt.lib") #pragma comment(lib, ".\\lib\\libmx.lib") #pragma comment(lib, ".\\lib\\libmat.lib") #pragma comment(lib, ".\\lib\\mclmcr.lib")#define WIDTH 512 #define HEIGHT 512int _tmain(int argc, _TCHAR* argv[]) {//mclInitializeApplication(NULL, 0);//mclmcrInitialize();UINT8 *img_befor = new UINT8[WIDTH*HEIGHT];DOUBLE *img_after = new DOUBLE[WIDTH*HEIGHT];int data;double ddata;FILE *fp;errno_t err = fopen_s(&fp, "pixel.txt", "r");if (err!=0){cout << "open pic fail!" << endl;return 0;}for (int i = 0; i < WIDTH; i++){for (int j = 0; j < HEIGHT; j++){fscanf_s(fp, "%d", &data);img_befor[i*WIDTH + j] = data;}}fclose(fp);fp = NULL;pcInitialize();mwArray img_input_array(HEIGHT, WIDTH, mxUINT8_CLASS, mxREAL);mwArray img_output_array(HEIGHT, WIDTH, mxDOUBLE_CLASS, mxREAL);int nargout = 1;img_input_array.SetData(img_befor, HEIGHT*WIDTH);phasecong(nargout,img_output_array,img_input_array);img_output_array.GetData(img_after, HEIGHT*WIDTH);pcTerminate();//將結果寫到文件err = fopen_s(&fp, "pixel_after.txt", "w");if (err != 0){cout << "open pic_after fail!" << endl;}else{//寫文件for (int i = 0; i < WIDTH; i++){for (int j = 0; j < HEIGHT; j++){ddata = img_after[i*WIDTH + j];fprintf(fp, "%.4f ", ddata);}fprintf(fp, "\n");}}fclose(fp);fp = NULL;return 0; }
原文:https://blog.csdn.net/w_b_h/article/details/74570852?
?
總結
以上是生活随笔為你收集整理的C++调用MATLAB函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python模块开发【Distutils
- 下一篇: MATLAB GPU加速