一、C++调用Matlab
http://social.msdn.microsoft.com/Forums/en-US/74ce2a70-1284-49c4-8c30-08184486c8f7/using-engineh-to-link-c-to-matlab?forum=vclanguage
1. 首先应确定Matlab正确安装,然后在系统环境变量PATH中加入一下路径:
C:\Program Files(x86)\MATLAB\R2010a\runtime\win32;C:\Program Files(x86)\MATLAB\R2010a\bin;C:\Program Files (x86)\MATLAB\R2010a\bin\win32;
其中Matlab路径根据自己的Matlab版本和路径、系统位数(32 or 64)自行调整。
注:如果有不同版本的Matlab(最好把不用的那个版本卸载,否则会出现问题),PATH中变量只能出现你调用的那个Matlab版本。
In (Computer->Properties->Advancedsystem settings->Environment Variables…->System variables->Path) , I removed anything related to my old MATLAB WIN64 andadded the following lines for my newly downloaded MATLAB WIN32:
C:\Program Files(x86)\MATLAB\R2010a\runtime\win32;C:\Program Files(x86)\MATLAB\R2010a\bin;C:\Program Files (x86)\MATLAB\R2010a\bin\win32;
Then I restarted mycomputer.
In Visual Studio2012, I added the following lines in the project (solution) properties:
ProjectProperties->Configuration Properties->VC++ Directories->ExcutableDirectories
C:\Program Files (x86)\MATLAB\R2010a\bin\win32
ProjectProperties->Configuration Properties->VC++ Directories->IncludeDirectories
C:\Program Files (x86)\MATLAB\R2010a\extern\include
ProjectProperties->Configuration Properties->VC++ Directories->LibraryDirectories
C:\Program Files (x86)\MATLAB\R2010a\extern\lib\win32\microsoft
ProjectProperties->Linker->Input->Additional Dependencies
libmx.lib
libeng.lib
libmex.lib
libmat.lib
#pragma comment(lib, "D:\\matlab lib\\libmat.lib")
#pragma comment(lib, "D:\\matlab lib\\libmx.lib")
#pragma comment(lib, "D:\\matlab lib\\libeng.lib")
注意:在2011版matlab中,libmatlib.lib更名为libmat.lib,matlab.h更名为mex.h。
Test Code:
#include "stdafx.h"
#include <iostream>
#include <math.h>
#include <D:\MatLab\extern\include\matlab.h >
#include <D:\MatLab\extern\include\engine.h >
#include <D:\MatLab\extern\include\matrix.h >
#include <vector>
#pragma comment(lib, "D:\\matlab lib\\libmx.lib")
#pragma comment (lib, "D:\\matlab lib\\libmat.lib")
#pragma comment(lib,"D:\\matlab lib\\libeng.lib")
#pragma comment(lib,"D:\\matlab lib\\libmatlb.lib")
#define vdou vector<double>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
Engine* eng;
if ( !( eng = engOpen(NULL) ) )
{
cout<<endl<< "error in open matlab"<<endl;
exit(1);
}
int count_node = 2;
//声明变量
mxArray* p_force_matlab = mxCreateDoubleMatrix(1,2*count_node,mxREAL);
mxArray* p_stiff_matlab = mxCreateDoubleMatrix(2*count_node,2*count_node,mxREAL);
mxArray* p_result_matlab = mxCreateDoubleMatrix(2*count_node,1,mxREAL);
int int_row_force = mxGetM(p_force_matlab);
int int_column_force = mxGetN(p_force_matlab);
int int_row_stiff = mxGetM(p_stiff_matlab);
int int_column_stiff = mxGetN(p_stiff_matlab);
vector< vector<double> > matr_stiffness;
matr_stiffness.resize(2*count_node,vdou(2*count_node,0.0));
for (int i = 0; i < 2*count_node; i++)
{
matr_stiffness[i][i] = 2.0;
}
vdou right_force;
right_force.resize(2*count_node);
for (int i = 0; i< 2*count_node;i++)
{
right_force[i] = i + 3 ;
}
//为二维数组赋值
double* pa = mxGetPr(p_stiff_matlab);
for (int i = 0;i < int_row_stiff;i++)
{
for (int j = 0;j < int_column_stiff;j++)
{
pa[i*int_column_force+j] = matr_stiffness[i][j];
}
}
//为一维数组赋值
double* pb = mxGetPr(p_force_matlab);
for (int i = 0;i < int_column_force;i++)
{
pb[i] = right_force[i];
}
vdou result(2*count_node,0.0);
double* pc = mxGetPr(p_result_matlab);
for (int i = 0;i < mxGetN(p_result_matlab);i++)
{
pc[i] = result[i] ;
}
//输入命令
engEvalString (eng, "clc;clear; ");
engPutVariable(eng, "f",p_force_matlab);
engPutVariable(eng,"ak",p_stiff_matlab);
engPutVariable(eng,"x",p_result_matlab);
engEvalString (eng, "ak ");
engEvalString (eng, "f ");
engEvalString (eng, "x = ak\\f' ");
//取出结果
p_result_matlab = engGetVariable(eng,"x");
pc = mxGetPr(p_result_matlab);
for (int i = 0;i < 2 * count_node;i++)
{
result[i] = pc[i];
}
//卸磨杀驴
mxDestroyArray(p_force_matlab);
mxDestroyArray(p_stiff_matlab);
engClose(eng);
for (int i = 0;i < 2*count_node;i++)
{
cout <<endl<<result[i]<<endl;
}
return 0;
}
二、Matlab调用C++来源:http://blog.sciencenet.cn/blog-43777-320103.html
- 如果用Matlab代码调用C++,需要现在Matlab中设置C++ compiler,即输入mex -setup,然后选择编译器即可。
在M文件中,加入 mex ***.cpp即可直接调用cpp中的函数。
通过MATLAB将C/C++函数编译成MEX函数,在MATLAB中就可以调用了。
1,首先装编译器
Matlab里键入mex -setup,选择你要编译C++的编译器
函数的形式必须是
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
nlhs:输出参数个数
plhs:输出参数列表
nrhs:输入参数个数
prhs:输入参数列表
,不过函数名可以随便取的。注意:保存的文件名就是将来在MATLAB中调用的函数名,而不是这里的函数名。
下面给出一个例子,目的是想截取数组的部分元素组成新的数组
输入参数3个,目标数组,截取的行(向量),截取的列(向量)
输出参数2个,截取后数组,数组维数信息
在函数中展示了如何传入传出参数,以及如果从参数列表中取出每一个参数,MATLAB数据和C++数据的互相转换,还有一些输出函数等。
新建一个ResizeArray.cpp文件(ResizeArray将作为MATLAB调用的函数名),写入下面代码
#include "mex.h"
//author: 汪帮主 2010.05.05
//MATLAB调用形式: [resizedArr, resizedDims] = ResizeArray(arr, selRows, sekCols)
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
if (nrhs != 3)
{
mexErrMsgTxt("参数个数不正确!");
}
int rowNum = mxGetM(prhs[0]);
int colNum = mxGetN(prhs[0]);
double* pArr = (double*)mxGetPr(prhs[0]);
//得到选择的行列信息
//无论是行向量还是列向量均支持
double* pSelRows = (double*)mxGetPr(prhs[1]);
double* pSelCols = (double*)mxGetPr(prhs[2]);
int selRowsRowNum = mxGetM(prhs[1]);
int selRowsColNum = mxGetN(prhs[1]);
if (selRowsRowNum!=1 && selRowsColNum!=1)
{
mexErrMsgTxt("行参数不正确!");
}
int selRowsNum = selRowsRowNum*selRowsColNum;
int selColsRowNum = mxGetM(prhs[2]);
int selColsColNum = mxGetN(prhs[2]);
if (selColsRowNum!=1 && selColsColNum!=1)
{
mexErrMsgTxt("列参数不正确!");
}
int selColsNum = selColsRowNum*selColsColNum;
plhs[1] = mxCreateDoubleMatrix(2, 1, mxREAL);
double* resizedDims = (double*)mxGetPr(plhs[1]);
resizedDims[0] = selRowsNum;
resizedDims[1] = selColsNum;
plhs[0] = mxCreateDoubleMatrix(selRowsNum, selColsNum, mxREAL);
double* pResizedArr =(double*)mxGetPr(plhs[0]);
//这里因为MATLAB中数据得按列优先
#define ARR(row,col) pArr[(col)*rowNum+row]
#define RARR(row,col) pResizedArr[(col)*selRowsNum+row]
for(int ri=0; ri<selRowsNum; ri++)
{
for(int ci=0; ci<selColsNum; ci++)
{
RARR(ri,ci)=ARR((int)pSelRows[ri]-1,(int)pSelCols[ci]-1);
}
}
mexPrintf("OK!\n");
}
3,编译C++函数为MEX函数
将ResizeArray.cpp放在MATLAB当前目录中,在MATLAB中输入mex ResizeArray.cpp,编译成功后将会生成ResizeArray.mexW32
4,调用函数
arr=[11:19;21:29;31:39;41:49;51:59;61:69];
selRows=[1 3];
selCols=[2:4 5 9];
[rarr,rdims]=ResizeArray(arr,rows,cols);
arr中数据:
11 12 13 14 15 16 17 18 19
21 22 23 24 25 26 27 28 29
31 32 33 34 35 36 37 38 39
41 42 43 44 45 46 47 48 49
51 52 53 54 55 56 57 58 59
61 62 63 64 65 66 67 68 69
rarr中数据:
12 13 14 15 19
32 33 34 35 39
rdims为:
2
5
OK,done!