声振论坛

 找回密码
 我要加入

QQ登录

只需一步,快速开始

查看: 7891|回复: 13

[混合编程] [转贴]VC6调用matlab7里的m程序的案例及方法

[复制链接]
发表于 2006-5-17 20:42 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?我要加入

x
VC + MATLAB7 C Shared Library
所有调用MATLAB7 Compiler产生的共享库的程序都具有如下的大致结构:
1. 声明变量或者是函数作为输入变量;
2. 调用 mclInitalizeApplication函数,并测试是否成功,该函数设置了一个全局的MCR状态,并且构建MCR实例;
3. 对于每个库,调用一次<libraryname>Initalize函数,为库创建一个MCR实例;
4. 调用库中的函数,并处理其结果(这是程序的主要部分);
5. 为每个库调用一次<libraryname>Terminate函数,用于注销相联系的MCR;
6. 调用mclTerminateApplication函数,释放与全局MCR状态相联系的资源;
7. 清除变换,关闭文件等,然后退出。
根据MATLAB的帮助文档中提供的例子,利用如下文件进行练习:
<matlabroot>/extern/examples/compiler/addmatrix.m
<matlabroot>/extern/examples/compiler/multiplymatrix.m
<matlabroot>/extern/examples/compiler/eigmatrix.m
实现步骤: (查询详细路径,确定要添加的库和头文件)
1) 先将这几个文件拷贝到当前目录下,然后利用mcc创建共享库,指令如下:
mcc -B csharedlib:libmatrix addmatrix.m multiplymatrix.m eigmatrix.m –v
其中,操作参数 -B csharedlib 是一个绑定的操作,其等效指令为 -W lib:<libname> -T link:lib。
2)在VC中创建一个MFC工程(本人创建的为基于对话框的),环境设置根据如下帖子:http://genial.yculblog.com/post.218721.html 指导进行。在本例子中,只需要在VC中进行如下步骤:
A. ToolsàOptionsàDirectoriesàShow directories for:Include filesà<matlab7root> \Extern\Include;
B. ToolsàOptionsàDirectoriesàShow directories for:Library filesà<matlab7root> \Extern\Lib\Win32\Microsoft\msvc60; (其它要包括的就是默认vc6相关的内容)
C. ProjectàSettingàC/C++àCategory:Code GenerationàUse run-time library:Debug Multithread DLL;
D. ProjectàSettingàLinkàCategory:InputàObject/library modules:mclmcrrt.lib libmatrix.lib(mcc生成的共享库)。
3)拷贝MATLAB当前目录下刚才用mcc生成的libmatrix.h,libmatrix.dll,libmatrix.lib,以及libmatrix.ctf,还有matlab中的mclmcrrt.lib文件到VC当前工程目录下,并用ProjectàAdd to ProjectàFiles…将libmatrix.h, mclmcrrt.lib加入到当前工程中。
4)在当前工程的对话框的头文件中加入#include "libmatrix.h" 与 #include "mclmcr.h";
5)在BOOL CMatlab7dllDlg::OnInitDialog()中进行MATLAB库文件的初始化,在void CMatlab7dllDlg::OnDestroy()中进行MATLAB库文件资源的释放,否则可能出现按钮只能够按一次,第二次运行则出错的现象;
6)调用MATLAB产生的库文件中函数的处理函数定义在一个按钮的响应函数中,并且要注意的是:如果一个mxArray变量需要重用的时候,必须用mxDestroyArray(out); out=0;即先进行变量注销,再设置为空。
附上这几个主要函数如下:
1.BOOL CMatlab7dllDlg::OnInitDialog()
{
CDialog::OnInitDialog();
……………
// TOD Add extra initialization here
/* Call the mclInitializeApplication routine. Make sure that the application
* was initialized properly by checking the return status. This initialization
* has to be done before calling any MATLAB API's or MATLAB Compiler generated
* shared library functions. */
if( !mclInitializeApplication(NULL,0) )
{
AfxMessageBox( "Could not initialize the application.");
exit(1);
}
/* Call the library intialization routine and make sure that the
* library was initialized properly. */
if (!libmatrixInitialize())
{
AfxMessageBox("Could not initialize the library.");
exit(1);
}
return TRUE; // return TRUE unless you set the focus to a control
}

2.void CMatlab7dllDlg::OnDestroy()
{
CDialog::OnDestroy();
/* Call the library termination routine */
libmatrixTerminate();
mclTerminateApplication();
}

3.void CMatlab7dllDlg::OnRUN()
{
CString str;
mxArray *in1, *in2; /* Define input parameters */
mxArray *out = NULL;/* and output parameters to be passed to the library functions */

double data[] = {1,2,3,4,5,6,7,8,9};

/* Create the input data */
in1 = mxCreateDoubleMatrix(3,3,mxREAL);
in2 = mxCreateDoubleMatrix(3,3,mxREAL);

memcpy(mxGetPr(in1), data, 9*sizeof(double));
memcpy(mxGetPr(in2), data, 9*sizeof(double));

/* Call the library function */
mlfAddmatrix(1, &out, in1, in2);
/* Display the return value of the library function */
str="The value of added matrix is:\n";
str = str + Display(out);
AfxMessageBox(str);

/* Destroy the return value since this varaible will be resued in
* the next function call. Since we are going to reuse the variable,
* we have to set it to NULL. Refer to MATLAB Compiler documentation
* for more information on this. */
mxDestroyArray(out); out=0;

mlfMultiplymatrix(1, &out, in1, in2);
str = "The value of the multiplied matrix is:\n";
str = str+Display(out);
AfxMessageBox(str);

mxDestroyArray(out); out=0;

mlfEigmatrix(1, &out, in1);
str = "The Eigen value of the first matrix is:\n";
str = str+Display(out);
AfxMessageBox(str);

mxDestroyArray(out); out=0;
/* Free the memory created */
mxDestroyArray(in1); in1=0;
mxDestroyArray(in2); in2 = 0;

AfxMessageBox("OK, Finished!");
} 4.CString CMatlab7dllDlg::Display(const mxArray *in)
{
CString str, strout=" ";
int i=0, j=0; /* loop index variables */
int r=0, c=0; /* variables to store the row and column length of the matrix */
double *data; /* variable to point to the double data stored within the mxArray */
/* Get the size of the matrix */
r = mxGetM(in);
c = mxGetN(in);
/* Get a pointer to the double data in mxArray */
data = mxGetPr(in);
/* Loop through the data and display the same in matrix format */
for( i = 0; i < c; i++ ){
for( j = 0; j < r; j++){
str.Format("%4.2f\t",data[i*c+j]);
strout = strout+str;
}
strout = strout+"\n";
}
strout = strout +"\n";
return strout;
}

5.附m文件:
1)addmatrix.m
function a = addmatrix(a1, a2)
%ADDMATRIX Add two matrices
% Copyright 2003 The MathWorks, Inc.
a = a1 + a2;

2) multiplymatrix.m
function m = multiplymatrix(a1, a2)
%MULTIPLYMATRIX Multiplies two matrices
% Copyright 2003 The MathWorks, Inc.
m = a1*a2;

3) eigmatrix.m
function e = eigmatrix(a1)
%EIGMATRIX Returns the eigen value of the given matrix
% Copyright 2003 The MathWorks, Inc.
e = eig(a1);

[ 本帖最后由 lxq 于 2007-7-7 20:21 编辑 ]
回复
分享到:

使用道具 举报

 楼主| 发表于 2006-5-17 20:50 | 显示全部楼层
该案例是在参看山城棒棒儿等前辈的资料上实现的,如果所调用的m程序含有绘图指令,需要察看相关头文件改变所调用的m文件名.
我现在毕设最后一个阶段需要用到vc调用rtw生成的代码来实现实时化.也希望路过的happy,suffer等大侠有好主意来帮帮我.多谢了! 我很希望能在此和大家分享所学的知识....

[ 本帖最后由 ChaChing 于 2010-5-4 23:31 编辑 ]
发表于 2006-5-17 21:52 | 显示全部楼层

回复:(zzpp321123)我现在毕设最后一个阶段需要用到...

是研究生毕业设计吗?很难吗?

[ 本帖最后由 ChaChing 于 2010-5-4 23:32 编辑 ]
发表于 2006-5-17 21:56 | 显示全部楼层
我是新手,大哥多多教我啊
 楼主| 发表于 2006-5-18 09:26 | 显示全部楼层

回复:是研究生毕业设计吗?很难吗?

是本科,主要之前课程的学习很少涉及这方面.vc及matlab还是边用边学.所以还希望大家能多帮帮我!!还有我不是大哥[em07],只是一直用同学注册的名字.
[此贴子已经被作者于2006-5-18 9:27:25编辑过]

发表于 2006-5-18 09:32 | 显示全部楼层

能否在这里找到会MatLab的救世主

<P>用Matlab编程实现下面算法:<BR>DBSCAN算法:从任意点P开始,检索所有从点p关于E和MinPts密度可达的点。</P>
<P>            如果p是核心点,就生成一个关于E和MinPts的簇;<BR>            <BR>            如果p是边界点,且没有从p密度可达的点,DBSCAN算法就访问数据库中下一个点。</P>
<P>            由于E和MinPts是全局参数值,如果两个不同密度的簇彼此接近,DBSCAN可能会合并这两个簇。</P>
<P>            当没有新的点添加到任何簇时,过程结束。<BR></P>
发表于 2006-6-30 13:56 | 显示全部楼层
能否请教一下,我按照楼主所说的操作,编译通过了,但是结果mclInitializeApplication(NULL,0)函数返回的是0,这是什么原因造成的
发表于 2006-7-12 09:47 | 显示全部楼层
我不太清楚这个,我一般是用matcom来做VC和MATLAB的混编
发表于 2006-9-6 21:05 | 显示全部楼层
楼主不厚道啊,该帖子在:

http://dreamseeking.spaces.live. ... DFC74BED3!137.entry

发表过了,难怪我也看得眼熟,应该是某人在回复帖子的时候发过
发表于 2006-9-6 21:55 | 显示全部楼层
呵呵,这个是很常见的,论坛的转贴是很正常的
只要不剽窃别人的就好了,不过转贴还是建议楼主表明出处

[ 本帖最后由 ChaChing 于 2010-5-4 23:35 编辑 ]
发表于 2006-9-6 21:57 | 显示全部楼层
我就是这个意思啊,因为一看题目就会误以为是原创的

[ 本帖最后由 ChaChing 于 2010-5-4 23:35 编辑 ]
发表于 2006-12-17 13:56 | 显示全部楼层

为什么出现mylibTerminate()出错

各位:我在用VC6调用matlab7里的m程序的案例及方法做混合编程,在VC++中运行时出现了以下信息:

Linking...
   Creating library Debug/mytest.lib and object Debug/mytest.exp
mytest.obj : error LNK2001: unresolved external symbol _mylibTerminate
mytest.obj : error LNK2001: unresolved external symbol _mlfMyfun
mytest.obj : error LNK2001: unresolved external symbol _mylibInitialize
Debug/mytest.dll : fatal error LNK1120: 3 unresolved externals
Error executing link.exe.

mytest.dll - 4 error(s), 0 warning(s)
请问这是什么原因呀?
发表于 2008-5-12 15:56 | 显示全部楼层
不注明转帖 就有侵权的危险罗:lol
发表于 2008-6-5 10:09 | 显示全部楼层

回复 楼主 的帖子

有没有个简单的例子呀
我想从最基本的设置开始
您需要登录后才可以回帖 登录 | 我要加入

本版积分规则

QQ|小黑屋|Archiver|手机版|联系我们|声振论坛

GMT+8, 2024-5-13 02:10 , Processed in 0.131425 second(s), 18 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表