Visual Studio 2010中的C++程序调用matlab程序代码 混合编程

本文目的:用matlab语言编写的程序函数可以通过参数接口在C++程序中调用,通过使用matlab生成dll形式,用C/C++程序调用!!!

环境配置:

1、环境及其所用工具:Window 7系统   matlab2012b  VS2010

2、这里注意下安装顺序,在安装matlab之前,一定要有VS软件在操作系统中 .否则在生成dll过程中,会找不到VS情况存在。

下面用matlab 2012b生成.dll、.lib、.h文件:

>>> mbuild -setup
Please choose your compiler for building standalone MATLAB applications: 
 
Would you like mbuild to locate installed compilers [y]/n? y
 
Select a compiler: 
[1] Lcc-win32 C 2.4.1 in C:\PROGRA~1\MATLAB\R2010b\sys\lcc 
[2] Microsoft Visual C++ 2010 in C:\Program Files\Microsoft Visual Studio 10.0 
[3] Microsoft Visual C++ 2008 SP1 in C:\Program Files\Microsoft Visual Studio 9.0 
 
[0] None 
 
Compiler: 2
 
Please verify your choices: 
 
Compiler: Microsoft Visual C++ 2010  
Location: C:\Program Files\Microsoft Visual Studio 10.0 
 
Are these correct [y]/n? y
 
**************************************************************************** 
  Warning: Applications/components generated using Microsoft Visual C++      
           2010 require that the Microsoft Visual Studio 2010 run-time       
           libraries be available on the computer used for deployment.       
           To redistribute your applications/components, be sure that the    
           deployment machine has these run-time libraries.                  
**************************************************************************** 
 
Trying to update options file: C:\Users\IDM\AppData\Roaming\MathWorks\MATLAB\R2010b\compopts.bat 
From template:              C:\PROGRA~1\MATLAB\R2010b\bin\win32\mbuildopts\msvc100compp.bat 
 
Done . . . 
以上为matlab中运行,主要是找到对应的VS版本。

然后,加入我们编写的.m文件为showimage.m,则:

<span style="color: rgb(68, 68, 68); font-family: 'courier new'; font-size: 14px; line-height: 15.4px; background-color: rgb(238, 238, 238);">mcc -W cpplib:showimage -T link:lib showimage.m</span>
mcc是编译为C接口的动态链接库。-W lib是将showimage.m编译为名为showimage的动态链接库。

另一种使用csharedlib捆绑命令也是等价的:
mcc -B csharedlib:showimage showimage.m

之后会生成一堆dll、lib、.h、.c等文件。</span>

参考链接:http://blog.csdn.net/xiaowei_cqu/article/details/7339356


通过以上步骤,你会得到在VS中要用到的动态库和静态库等文件。

下面要配置VS2010中的环境:


基本按照下面链接中的步骤进行了,执行完毕后,经测试并没有问题。


VS2010环境配置



并使用如下代码进行测试:

#include "stdafx.h"
#include <iostream>
#include <stdio.h>
#include "libAdd.h"
#include "showimage.h"
#include "engine.h"

#include <stdlib.h>
#include <string.h>
#include "matrix.h"

using namespace std;


#define BUFSIZE 256

int main()
{
if (!showimageInitialize())
	{
		return -1;
	}
//测试两个整数相加
	int a = 10;
	int b = 20;
	int c;

	mwArray mwA(1,1,mxINT32_CLASS);
	mwArray mwB(1,1,mxINT32_CLASS);
	mwArray mwC(1,1,mxINT32_CLASS);

	mwA.SetData(&a,1);
	mwB.SetData(&b,1);
	add(1, mwC, mwA, mwB);
	c = mwC.Get(1,1);
	cout<<"c = "<<c<<endl<<endl;

	//测试两个double型矩阵相加

	double da[2][2] = {1,2,3,4}, db[2][2] = {5,6,7,8};
	double dc[2][2];
	mwArray mwDA(2,2,mxDOUBLE_CLASS);
	mwArray mwDB(2,2,mxDOUBLE_CLASS);
	mwArray mwDC(2,2,mxDOUBLE_CLASS);
	mwDA.SetData(*da, 4);
	mwDB.SetData(*db, 4);
	add(1, mwDC, mwDA, mwDB);
	cout<<"dc = "<<endl;
	for(int i = 0; i < 2; i++)
	{
		for(int j = 0; j < 2; j++)
		{
			dc[i][j] = mwDC.Get(2,j+1,i+1);

            cout<<"  "<<dc[i][j];
		}
		cout<<endl;
	}
	//自定义程序测试
	double ta[1][4] = {1,2,3,4};
	double tb[1][4] = {5,6,7,8};
	double tc[1][4];

	mwArray mwTA(4,4,mxDOUBLE_CLASS);
	mwArray mwTB(4,4,mxDOUBLE_CLASS);
	mwArray mwTC(4,4,mxDOUBLE_CLASS);

	mwTA.SetData(*ta, 4);
	mwTB.SetData(*tb, 4);

	add(1, mwTC, mwTA, mwTB);

	cout<<"tc = "<<endl;
	for(int i = 0; i < 1; i++)
	{
		for(int j = 0; j < 4; j++)
		{
			tc[i][j] = mwTC.Get(2,j+1,i+1);

			cout<<"  "<<tc[i][j];
		}
		cout<<endl;
	}

}

结果即为两者相加的和。

以上程序中函数说明:

(1) 第7行初始化lib的代码貌似是必须的,否则我这里运行出错;而第44行和第45行的终止调用,

貌似注释掉也没有什么影响。
(2) mwArray对象有多种初始化方式,这里第13-15行表示初始化成1x1的int32类型对象,

第25-27行表示初始化成2x2的double类型对象。
(3) SetData函数第一个参数是一个mwArray型的一级指针,第二个参数表示元素个数。由于a,b

是一个int型的变量,故第16-17行对a,b做取地址运算;而da和db由于是二维数组名,即二级指针

常量,故第28-29行对da,db做了一级指针引用。
(4) Get函数也有多种调用形式。第19行调用中,Get函数第一个参数1,表示只用1个下标来访问

(类似于MATLAB中可以把一个矩阵看作是一个向量,以列为先序),第二个参数1表示访问第1

个元素;而第37行调用中,Get函数第一个参数2,表示用2个下标来访问(i是行索引,j是列索引

,又由于是以列为先序,所以j在前,i在后),同时由于MATLAB中下标是从1开始,而C++中下

标是从0开始,故做了j+1和i+1操作。


并且通过调用一些其他函数,调用matlab中的画图操作。测试代码如下:

#include "stdafx.h"
#include <iostream>
#include <stdio.h>
#include "libAdd.h"
#include "showimage.h"
#include "engine.h"

#include <stdlib.h>
#include <string.h>
#include "matrix.h"


using namespace std;

#define BUFSIZE 256

int _tmain(int argc, _TCHAR* argv[])
{
	//mclTerminateApplication();
	//一定要有这个才能使用<span style="font-family: Arial, Helvetica, sans-serif;">mxCreateDoubleMatrix分配空间</span>
	mclInitializeApplication(NULL,0);


	Engine *ep;
	mxArray *T = NULL, *result = NULL;
	
	char buffer[BUFSIZE+1];
	double time[10] = { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0 };


	if (!(ep = engOpen("\0"))) {
		fprintf(stderr, "\nCan't start MATLAB engine\n");
		return EXIT_FAILURE;
	}


	T = mxCreateDoubleMatrix(1, 10, mxREAL);

	memcpy((void *)mxGetPr(T), (void *)time, sizeof(time));

	engPutVariable(ep, "T", T);


	engEvalString(ep, "D = .5.*(-9.8).*T.^2;");


	engEvalString(ep, "plot(T,D);");
	engEvalString(ep, "title('Position vs. Time for a falling object');");
	engEvalString(ep, "xlabel('Time (seconds)');");
	engEvalString(ep, "ylabel('Position (meters)');");


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

	printf("Done for Part I.\n");
	mxDestroyArray(T);
	engEvalString(ep, "close;");





	buffer[BUFSIZE] = '\0';
	engOutputBuffer(ep, buffer, BUFSIZE);
	while (result == NULL) {
		char str[BUFSIZE+1];

		printf("Enter a MATLAB command to evaluate. This command should\n");
		printf("create a variable X. This program will then determine\n");
		printf("what kind of variable you created.\n");
		printf("For example: X = 1:5\n");
		printf(">> ");

		fgets(str, BUFSIZE, stdin);


		engEvalString(ep, str);


		printf("%s", buffer+2);


		printf("\nRetrieving X...\n");
		if ((result = engGetVariable(ep,"X")) == NULL)
			printf("Oops! You didn't create a variable X.\n\n");
		else {
			printf("X is class %s\t\n", mxGetClassName(result));
		}
	}


	printf("Done!\n");
	mxDestroyArray(result);
	engClose(ep);

	return EXIT_SUCCESS;
}

以上程序运行结果为:



画一朵花程序:

#include "stdafx.h"
#include <iostream>
#include <stdio.h>
#include "libAdd.h"
#include "showimage.h"
#include "engine.h"

#include <stdlib.h>
#include <string.h>
#include "matrix.h"
#include "showia.h"

using namespace std;


#define BUFSIZE 256

int _tmain(int argc, _TCHAR* argv[])
{

	//mclTerminateApplication();
	//一定要有这个才能赋值
	mclInitializeApplication(NULL,0);
	Engine *ep;

	
	if (!(ep = engOpen("\0"))) {
		fprintf(stderr, "\nCan't start MATLAB engine\n");
		return EXIT_FAILURE;
	}

	engEvalString(ep, "x=-8:0.5:8;");
	engEvalString(ep, "y=x;");
	engEvalString(ep, "[Y,X]=meshgrid(y,x);");
	engEvalString(ep, "R=sqrt(X.^2+Y.^2)+eps;");
	engEvalString(ep, "Z=2*sin(R)./R;");
	engEvalString(ep, "surf(X,Y,Z);");
}


参考链接:

http://blog.sina.com.cn/s/blog_78ee50ce0102voy8.html


http://blog.sina.com.cn/s/blog_4cac891f0100ui0x.html


  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值