|
Posted on 2006-12-02 20:14 济公 阅读(4297) 评论(11) 编辑 收藏 引用 所属分类: VCMatlab
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 –v -B csharedlib:libmatrix addmatrix.m multiplymatrix.m eigmatrix.m
其中,操作参数
-B csharedlib
是一个绑定的操作,其等效指令为
-W lib:<libname> -T link:lib
。
2
)在
VC
中创建一个
MFC
工程(本人创建的为基于对话框的),环境设置根据如下帖子:
怎样设置
Visual Studio
与
Matlb Complier 4.0
一起工作
中的指导进行。在本例子中,只需要在
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
;
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
文件到
VC
当前工程目录下,并用
Project->Add to Project->Files…
将
libmatrix.h
加入到当前工程中。
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(); …………… // TODO: 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);
发布到目标机器上的时候需要拷贝过去的文件有:
MCRInstaller.exe
,工程文件的可执行程序,共享库
(DLL)
,共享库对应的
.ctf
文件。点击运行
MCRInstaller.exe
文件,安装好
MCR
之后,将
<mcr_root>\runtime\win32
加入到系统的环境变量
path
中去
Feedback
# re: VC6调用matlab7里的m程序的案例及方法 回复 更多评论
2007-05-16 13:45 by
兄弟这篇文章很好,谢谢啦!
# re: VC6调用matlab7里的m程序的案例及方法 回复 更多评论
2007-06-06 20:11 by
请问一下,我在matlabR2006b下按照您这篇文章操作,到VC编译通过后总是说“Could not initialize the library.“(libmatrixInitialize()那部分),因为是初次尝试混编,实在不明白自己那里做错了,望您能指点一下,谢谢
# re: VC6调用matlab7里的m程序的案例及方法 回复 更多评论
2007-06-07 09:36 by
TO:feiyeying
你用7.0吧
# re: VC6调用matlab7里的m程序的案例及方法 回复 更多评论
2007-06-16 21:50 by
我用的是7.0,也出现了“Could not initialize the library.“的问题
# re: VC6调用matlab7里的m程序的案例及方法 回复 更多评论
2007-07-29 03:03 by
我的是7.0,还没出Could not initialize the library,运行时直接就是说出现问题,程序需要关闭,我在libmatrixInitialize()处放断点调试,一执行这句就弹出对话框 unhandled exception in ***.exe :0XC0000005 :Acceess violation.
请问有人知道什么原因么?
急啊!
# re: VC6调用matlab7里的m程序的案例及方法 回复 更多评论
2007-08-08 17:55 by
那位知道libmatrixInitialize()初始化失败的原因?谢谢
# re: VC6调用matlab7里的m程序的案例及方法 回复 更多评论
2007-12-03 16:55 by
我的是7.1,
# re: VC6调用matlab7里的m程序的案例及方法 回复 更多评论
2007-12-03 16:59 by
我的是7.1,完全按上面的方法进行。但编译时出现
'mlfAddmatrix' : undeclared identifier
C:\Documents and Settings\Administrator\桌面\ytexamp\ytexampDlg.cpp(221) : error C2065: 'mlfMultiplymatrix' : undeclared identifier
C:\Documents and Settings\Administrator\桌面\ytexamp\ytexampDlg.cpp(229) : error C2065: 'mlfEigmatrix' : undeclared identifier
Error executing cl.exe.
ytexampDlg.obj - 3 error(s), 0 warning(s)
为什么?
# re: VC6调用matlab7里的m程序的案例及方法 回复 更多评论
2007-12-03 17:05 by
查看libmatrix.h头文件后,将上述三个函数该为 头中定义如下:LIB_libmatrix_CPP_API void addmatrix(int nargout, mwArray& a
, const mwArray& a1
, const mwArray& a2);
extern LIB_libmatrix_CPP_API void multiplymatrix(int nargout, mwArray& m
, const mwArray& a1
, const mwArray& a2);
extern LIB_libmatrix_CPP_API void eigmatrix(int nargout, mwArray& e
, const mwArray& a1);
改为直接调用后出现\Documents and Settings\Administrator\桌面\ytexamp\ytexampDlg.cpp(206) : error C2664: 'addmatrix' : cannot convert parameter 2 from 'struct mxArray_tag *' to 'class mwArray
请教大虾?
# re: VC6调用matlab7里的m程序的案例及方法 回复 更多评论
2007-12-04 15:51 by
TO:yt
我长时间没有用这东西,我现在电脑上也没装Matlab,没法给你测试。上面说的还算比较清楚,你好好调试下,看看环境的设置搞好了没有等。
# re: VC6调用matlab7里的m程序的案例及方法 回复 更多评论
2008-03-13 20:46 by
很好,支持,环境变量要配置好,不要和其他的程序发生冲突
我的和IBM的DB2下面的dll发生了冲突,给了好大的劲才搞好了,大家以后要注意啊
|