C/C++調用Matlab程序

在用C寫程序時,有時會遇到數值計算問題,如矩陣的計算、優化問題、解微分方程等等。這些數值計算問題如果自己來實現的話,一來太費時間,二來自己的實現方案效率未必高。所以遇到這些數值計算問題時可以先上網搜一下,看看有沒有現成的模塊(當然要可靠)。另一種解決方法就是依靠matlab了。用過matlab 的人都知道,它提供了豐富的數值計算函數。在C程序中調用matlab函數即可輕鬆解決問題。

在進行聯合編程前需要經行配置

1 Visual Studio的配置(VS2008爲例)

選擇"工具"→"選項"→"VC++目錄",如下圖所示添加路徑

2matlab的配置

在matlab命令行輸入mex -setup,按提示選擇合適的選項

在matlab命令行輸入mbuild -setup,按提示選擇合適的選項

 

以上配置只需進行一次就可以了,不必每寫一個程序都重複一遍。

 

 

在C中調用matlab有兩種方法:1 在C程序中調用matlab引擎 2 matlab函數編譯生成dll文件供C程序使用。以下分別介紹

1在C程序中調用matlab引擎

爲了調用matlab引擎,首先需要引入相應的頭文件

#include "engine.h"

然後需要加如下幾行代碼,這樣順利地完成連接。

#pragma comment( lib, "libeng.lib" )

#pragma comment( lib, "libmx.lib" )

#pragma comment( lib, "libmat.lib" )

有時候你可程序所調用的函數可能還需要其他的庫。如果有鏈接錯誤提示的話,上網搜一下,然後按上述格式把需要的庫加上就可以了。

接下來就可以在需要的地方調用matlab引擎了。使用時首先需要打開引擎:

Engine *ep;

if (!(ep = engOpen("\0")))

{

fprintf(stderr, "\nCan't start MATLAB engine\n");

return EXIT_FAILURE;

}

接下來將C程序中相關的變量變爲matlab需要的格式,一般使用mxCreateDoubleMatrix 和 memcpy函數。

完成轉換後使用engPutVariable將數據送到matlab引擎。

最後調用engEvalString,將matlab命令作爲其參數,就可以利用matlab引擎進行計算了。

計算完成後不要忘了清理工作: 使用mxDestroyArray清除mxCreateDoubleMatrix產生的變量,最後使用engClose關閉引擎。

下面是一個例子,繪製y=sin(t)的圖像

代碼:

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#include "engine.h"

 

#pragma comment( lib, "libeng.lib" )

#pragma comment( lib, "libmx.lib" )

#pragma comment( lib, "libmat.lib" )

 

int main()

{

Engine *ep;

if (!(ep = engOpen("\0")))

{

fprintf(stderr, "\nCan't start MATLAB engine\n");

return EXIT_FAILURE;

}

 

int Nsample = 50;

const double PI = 3.1415926;

double *= new double[Nsample] ;

 

for(int i = 0; i < Nsample; i++)

{

t[i] = i * 2 * PI / Nsample;

}

 

 

mxArray *= NULL, *result = NULL;

= mxCreateDoubleMatrix(1, Nsample, mxREAL);

memcpy((void *)mxGetPr(T), (void *)t, Nsample*sizeof(t[0]));

 

engPutVariable(ep, "T", T);

engEvalString(ep, "Y=sin(T);");

engEvalString(ep, "plot(T,Y);");

engEvalString(ep, "title('y=sin(t)');");

engEvalString(ep, "xlabel('t');");

engEvalString(ep, "ylabel('y');");

 

printf("Hit return to continue\n\n");

fgetc(stdin);

 

mxDestroyArray(T);

engEvalString(ep, "close;");

 

engClose(ep);

return EXIT_SUCCESS;

}

執行結果

 

2 C程序調用matlab生成的dll

如果需要matlab完成的功能比較通用,如果用上述方法,則會產生大量的重複代碼。這裏要講的方法將對matlab 的調用做成一個模塊,這樣每次使用時只需調用這個模塊就可以了。

首先將需要matlab完成的功能做成一個matlab函數,然後利用mcc命令編譯,得到h、dll、lib等文件,在C工程中只需加入上述文件即可。下面是一個例子。

在做通信仿真時通常是給地一組信噪比,然後通過仿真得到在每個信噪比下的誤碼率,最後繪製出誤碼率對信噪比的曲線。

以前的做法是用C仿真,並將結果存在txt文件中,最後讓matlab從txt文件中讀取數據並繪圖。

利用這裏的方法,可以寫一個matlab繪圖的模塊,並在C程序的最後調用,這樣就能自動完成繪圖了。

Matlab代碼

function showBER(SNR_indB,BER)

semilogy(SNR_indB,BER,'-o','linewidth',2);

grid on

xlabel('E_b/N_0(dB)');

ylabel('BER');

 

在matlab命令行中輸入

mcc -B csharedlib:showBER showBER.m

得到一組文件

將其中的.dll .h .lib文件拷貝到C工程中。

在需要調用繪圖模塊的cpp文件中加入如下代碼

#include "showBER.h"

#pragma comment( lib, "libeng.lib" )

#pragma comment( lib, "libmx.lib" )

#pragma comment( lib, "libmat.lib" )

#pragma comment( lib, "mclmcrrt.lib" )

#pragma comment( lib, "showBER.lib" )

 

下面的一段代碼顯示了調用繪圖模塊的方法:

double SNR[] = {0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4,1.5};

double BER[] = {9.728816e-002, 8.099609e-002, 5.633803e-002,3.733608e-002, 1.253970e-002, 3.936489e-003, 1.206820e-003, 2.104052e-004, 3.109879e-005, 3.365857e-006, 2.565067e-007};

int len = sizeof(SNR) / sizeof(SNR[0]);

 

showBERInitialize();

 

mxArray* xSNR = mxCreateDoubleMatrix(1, len, mxREAL);

memcpy(mxGetPr(xSNR), (void*)SNR, sizeof(SNR));

mxArray* xBER = mxCreateDoubleMatrix(1, len, mxREAL);

memcpy(mxGetPr(xBER), (void*)BER, sizeof(BER));

 

mlfShowBER(xSNR,xBER);

system("PAUSE");

 

showBERTerminate();

 

1在調用繪圖模塊之前需要調用showBERInitialize

2在調用繪圖模塊之後需要調用showBERTerminate

3使用mxCreateDoubleMatrix 和 memcpy 函數將C程序中的變量送入matlab中

4通過mlfShowBER調用matlab模塊。而mlf***函數的調用格式需要參考***.h(此例爲showBER.h)文件中的聲明。

 

運行結果爲

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章