基于VS2008和Matlab R2010b版本的混合编程的实现(转自:http://blog.sina.com.cn/s/blog_49cb42490100nm5j.html)
2011-06-30 19:35
666 查看
众所周知Matlab的强大运算能力让各种工程软件望而却步,而VC程序的友好界面又让人爱不释手,如果能够让两者的优势结合起来的话,势必能让程序员欢欣鼓舞。还好MathWorks已经为我们想到了,基本上现在市面上主流的Matlab版本都可以支持VC和Matlab的混合编程。但是目前网上资料基本上都是基于Matlab 6.0和VC 6.0的,和新版本的实现方法有所不同,因此笔者通过不断的尝试和研究,终于调试通了基于VS2008和Matlab R2010b的混合编程。
为了更加直观的说明如何实现混合编程,笔者写了一个简单的程序作为测试。先在Matlab里面写一个M文件,代码如下:
function b = MyFunc(a)
b = a*a;
将M文件保存为MyFunc.m,保存在F:/test文件夹中。然后在Matlab主窗口中将当前文件夹改为F:/test:
cd F:/test;
为了能够让VC调用Matlab程序,我们可以采用将Matlab程序包装成动态链接文件DLL的形式,然后让VC调用动态链接文件,因此在Matlab中,我们需要设置一下Matlab的编译库,在Matlab主窗口中键入如下代码:
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 D:/PROGRA~1/MATLAB/R2010b/sys/lcc
[2] Microsoft Visual C++ 2008 SP1 in D:/Program Files/Microsoft Visual Studio 9.0
[0] None
Compiler:
由于我们是需要用VC来调用Matlab函数,因此我们选择2,回车,出现
Please verify your choices:
Compiler: Microsoft Visual C++ 2008 SP1
Location: D:/Program Files/Microsoft Visual Studio 9.0
Are these correct [y]/n?
确定,键入y后回车,出现
****************************************************************************
Warning: Applications/components generated using Microsoft Visual Studio
2008 require that the Microsoft Visual Studio 2008 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/张智宇/AppData/Roaming/MathWorks/MATLAB/R2010b/compopts.bat
From template: D:/PROGRA~1/MATLAB/R2010b/bin/win32/mbuildopts/msvc90compp.bat
Done . . .
如果出现以上说明,则证明Matlab编译器设置成功了。接下来是生成M文件的DLL文件。
在Matlab主窗口中键入如下代码
mcc -W cpplib:MyDLL -T link:lib MyFunc.m
其中cpplib:后面的是需要生成文件的文件名,是自己取的,link:lib后面的MyFunc.m是转换为DLL的M文件的文件名。 -W/-T/-C是参数,具体含义可以通过mcc –help命令查看,注意参数的大小写。
Matlab编译后会在Test文件夹下生成9个文件,分别是:
mccEcxludedFiles.log
MyDLL.cpp
MyDLL.ctf
MyDLL.dll
MyDLL.exp
MyDLL.exports
MyDLL.h
MyDLL.lib
readme.txt
其中MyDLL.dll,MyDLL.lib,MyDLL.ctf,MyDLL.h是我们需要的文件,至此,Matlab方面就已经设置妥当了。
打开VC2008,新建一个工程,然后将上述四个文件复制到工程目录下。选择“工具-选项-项目和解决方案-VC++目录”,在“显示以下内容目录”里选择“包含文件”将“D:/Program Files/MATLAB/R2010b/extern/include”添加进去,然后选择“库文件”将“D:/Program Files/MATLAB/R2010b/extern/lib/win32/microsoft”添加进去,其中D:/Program Files是Matlab的安装目录,可根据实际情况进行修改。
然后选择“项目-属性-配置属性-链接器-输入”,在右边“附加依赖项”一栏填入“myDLL.lib mclmcrrt.lib”,其中MyDLL.lib就是刚刚用Matlab生成的lib文件。
在编写代码时首先得包含头文件“MyDLL.h”,然后开始编写需要的代码,我为了说明问题编写了一个测试代码如下所示:
#include "libMyFunc.h"
#include <iostream>
using namespace std;
int main()
{
libMyFuncInitialize(); //初始化DLL动态连接文件
double _x[1] = {5}; //输入数组
double _y[1]; //输出数组
mxArray* x = mxCreateDoubleMatrix(1, 1, mxREAL); //创建1*5矩阵
memcpy(mxGetPr(x), (void*)_x, sizeof(_x)); //拷贝输入数据
mxArray *input[1] = {x}; //将矩阵x的指针作为输入参数传递进去
mxArray *output[1]; //定义输出参数指针
mlxMyFunc(1,output,1,input); //调用m函数
mxArray *y; //定义输出结果指针
y = output[0]; //将输出参数传递给输出结果
memcpy(_y, mxGetPr(y), sizeof(_y)); //拷贝输出数据
//显示数组中的数据
cout << _y[0] << endl;
libMyFuncTerminate(); //结束DLL库
system("pause");
return 0;
}
其中MyDLLInitialize(),mlxMyFunc(),MyDLLTerminate()等函数可以在MyDLL.h中找到函数原型,mlxMyFunc函数原型为:
mlxMyFunc(int nlhs, mxArray *plhs[], int nrhs, mxArray *prhs[])
nlhs代表输出参数个数,plhs[]里面存放的是输出参数的指针,nrhs代表输入参数个数,prhs[]中存放的是输入参数的指针。上例中由于输入输出参数只有一个,因此在plhs[0]中存放的就是M文件中b的指针,prhs[0]中存放的就是M文件中a的指针。
编译运行之后就可以在控制台中输出所要的结果。将项目文件夹下生成的可执行文件复制出来,将MyDLL.dll文件、MyDLL.ctf文件和.exe文件放在同一目录下便可脱离VC++独立运行。如果需要在其他未装Matlab的机器上运行,则还需要将“D:/Program Files/MATLAB/R2010b/toolbox/compiler/deploy/win32”中的MCRInstaller.exe复制出来,在未安装Matlab的电脑上运行此程序,才可使得刚刚生成的可执行文件顺利运行。
为了更加直观的说明如何实现混合编程,笔者写了一个简单的程序作为测试。先在Matlab里面写一个M文件,代码如下:
function b = MyFunc(a)
b = a*a;
将M文件保存为MyFunc.m,保存在F:/test文件夹中。然后在Matlab主窗口中将当前文件夹改为F:/test:
cd F:/test;
为了能够让VC调用Matlab程序,我们可以采用将Matlab程序包装成动态链接文件DLL的形式,然后让VC调用动态链接文件,因此在Matlab中,我们需要设置一下Matlab的编译库,在Matlab主窗口中键入如下代码:
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 D:/PROGRA~1/MATLAB/R2010b/sys/lcc
[2] Microsoft Visual C++ 2008 SP1 in D:/Program Files/Microsoft Visual Studio 9.0
[0] None
Compiler:
由于我们是需要用VC来调用Matlab函数,因此我们选择2,回车,出现
Please verify your choices:
Compiler: Microsoft Visual C++ 2008 SP1
Location: D:/Program Files/Microsoft Visual Studio 9.0
Are these correct [y]/n?
确定,键入y后回车,出现
****************************************************************************
Warning: Applications/components generated using Microsoft Visual Studio
2008 require that the Microsoft Visual Studio 2008 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/张智宇/AppData/Roaming/MathWorks/MATLAB/R2010b/compopts.bat
From template: D:/PROGRA~1/MATLAB/R2010b/bin/win32/mbuildopts/msvc90compp.bat
Done . . .
如果出现以上说明,则证明Matlab编译器设置成功了。接下来是生成M文件的DLL文件。
在Matlab主窗口中键入如下代码
mcc -W cpplib:MyDLL -T link:lib MyFunc.m
其中cpplib:后面的是需要生成文件的文件名,是自己取的,link:lib后面的MyFunc.m是转换为DLL的M文件的文件名。 -W/-T/-C是参数,具体含义可以通过mcc –help命令查看,注意参数的大小写。
Matlab编译后会在Test文件夹下生成9个文件,分别是:
mccEcxludedFiles.log
MyDLL.cpp
MyDLL.ctf
MyDLL.dll
MyDLL.exp
MyDLL.exports
MyDLL.h
MyDLL.lib
readme.txt
其中MyDLL.dll,MyDLL.lib,MyDLL.ctf,MyDLL.h是我们需要的文件,至此,Matlab方面就已经设置妥当了。
打开VC2008,新建一个工程,然后将上述四个文件复制到工程目录下。选择“工具-选项-项目和解决方案-VC++目录”,在“显示以下内容目录”里选择“包含文件”将“D:/Program Files/MATLAB/R2010b/extern/include”添加进去,然后选择“库文件”将“D:/Program Files/MATLAB/R2010b/extern/lib/win32/microsoft”添加进去,其中D:/Program Files是Matlab的安装目录,可根据实际情况进行修改。
然后选择“项目-属性-配置属性-链接器-输入”,在右边“附加依赖项”一栏填入“myDLL.lib mclmcrrt.lib”,其中MyDLL.lib就是刚刚用Matlab生成的lib文件。
在编写代码时首先得包含头文件“MyDLL.h”,然后开始编写需要的代码,我为了说明问题编写了一个测试代码如下所示:
#include "libMyFunc.h"
#include <iostream>
using namespace std;
int main()
{
libMyFuncInitialize(); //初始化DLL动态连接文件
double _x[1] = {5}; //输入数组
double _y[1]; //输出数组
mxArray* x = mxCreateDoubleMatrix(1, 1, mxREAL); //创建1*5矩阵
memcpy(mxGetPr(x), (void*)_x, sizeof(_x)); //拷贝输入数据
mxArray *input[1] = {x}; //将矩阵x的指针作为输入参数传递进去
mxArray *output[1]; //定义输出参数指针
mlxMyFunc(1,output,1,input); //调用m函数
mxArray *y; //定义输出结果指针
y = output[0]; //将输出参数传递给输出结果
memcpy(_y, mxGetPr(y), sizeof(_y)); //拷贝输出数据
//显示数组中的数据
cout << _y[0] << endl;
libMyFuncTerminate(); //结束DLL库
system("pause");
return 0;
}
其中MyDLLInitialize(),mlxMyFunc(),MyDLLTerminate()等函数可以在MyDLL.h中找到函数原型,mlxMyFunc函数原型为:
mlxMyFunc(int nlhs, mxArray *plhs[], int nrhs, mxArray *prhs[])
nlhs代表输出参数个数,plhs[]里面存放的是输出参数的指针,nrhs代表输入参数个数,prhs[]中存放的是输入参数的指针。上例中由于输入输出参数只有一个,因此在plhs[0]中存放的就是M文件中b的指针,prhs[0]中存放的就是M文件中a的指针。
编译运行之后就可以在控制台中输出所要的结果。将项目文件夹下生成的可执行文件复制出来,将MyDLL.dll文件、MyDLL.ctf文件和.exe文件放在同一目录下便可脱离VC++独立运行。如果需要在其他未装Matlab的机器上运行,则还需要将“D:/Program Files/MATLAB/R2010b/toolbox/compiler/deploy/win32”中的MCRInstaller.exe复制出来,在未安装Matlab的电脑上运行此程序,才可使得刚刚生成的可执行文件顺利运行。
相关文章推荐
- 求两个数组的交集、并集和差集算法分析与实现(转自http://blog.sina.com.cn/s/blog_616e189f0100mrdn.html)
- VC++实现Contourlet图像处理[转载自http://blog.sina.com.cn/aclon]支持原创
- 【数据结构】排序算法总结及php排序算法实现代码(伪代码见 http://blog.sina.com.cn/s/blog_676a011e0100ty5o.html)
- 理解并发编程的几种"性" -- 可见性,有序性,原子性 http://blog.sina.com.cn/s/blog_4adc4b090102whzx.html
- 教你如何查看CAD文件是哪个版本的来自http://blog.sina.com.cn/s/blog_4c9fa4dd0101il1v.html
- 基于VS2010和Matlab R2010b版本的混合编程的实现
- 使用VAssistX为VS2008 c++代码添加函数头注释http://blog.sina.com.cn/s/blog_4aff4b970101bfqs.html
- ----------------http://blog.sina.com.cn/s/blog_5da93c8f0101hnzx.html
- 关于Unicode字符集(http://blog.sina.com.cn/s/blog_4b4409c30100vw9t.html)
- 瞬间状态摄影实验 (更多--http://blog.sina.com.cn/rongjianqun)
- 已发布13集网站开发技术视频:http://blog.sina.com.cn/s/blog_67d27f340102vf7l.html
- http://blog.sina.com.cn/yahuizhao
- http://blog.sina.com.cn/s/blog_4e6dffee0100hid1.html
- http://blog.sina.com.cn/aszhangguoqing
- http://blog.sina.com.cn/s/blog_6940cab30101hn9j.html
- 转自http://blog.sina.com.cn/daylive——C++ STL set&multiset
- struts2 validation.xml 验证 http://blog.sina.com.cn/s/blog_57554ed50100e81l.html
- CImage类 from http://blog.sina.com.cn/s/blog_487547aa0100an6k.html
- 【转载--http://blog.sina.com.cn/s/blog_4488002e0100z574.html】mysql忘记密码
- 多线程消息队列 (MSMQ) 触发器 -http://blog.sina.com.cn/s/blog_405ad00201007rlw.html