C++调用Matlab && Matlab调用C++

本文详细介绍了如何在C++中调用MATLAB以及MATLAB调用C++的方法,包括环境配置、代码实现及实例解析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、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中的函数。

通过MATLABC/C++函数编译成MEX函数,在MATLAB中就可以调用了。

1,首先装编译器
Matlab里键入mex -setup,选择你要编译C++的编译器

2,写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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值