Matlab75a函数转换成VC++60动态链接库修改.docx
- 文档编号:12231922
- 上传时间:2023-04-17
- 格式:DOCX
- 页数:16
- 大小:22.69KB
Matlab75a函数转换成VC++60动态链接库修改.docx
《Matlab75a函数转换成VC++60动态链接库修改.docx》由会员分享,可在线阅读,更多相关《Matlab75a函数转换成VC++60动态链接库修改.docx(16页珍藏版)》请在冰豆网上搜索。
Matlab75a函数转换成VC++60动态链接库修改
Matlab7.0函数转换成VC++6.0动态链接库[转+修改]
1、mcc4.0编译环境设置
在桌面上右键单击“我的电脑”图标出现以下菜单
单击“属性”菜单项,出现“系统特性”对话框,单击“高级”选项卡,如下图所示
在上图中,单击“环境变量”按钮,出现“环境变量”对话框,添加系统变量matlab值为C:
\MATLAB7即matlab7.0的安装路径,如下图所示
在环境变量path中加入C:
\MATLAB7\bin\win32,如下图所示
按“确定”完成设置后,重启计算机或注销当前用户,即可应用新设置。
2、Matlab7.0编译器设置
(1)mex命令设置
(a)运行Matlab,在Matlab的命令窗口(CommandWindow)键入“mex-setup”命令后,按回车键,安装Matlab编译器;
(b)命令窗口出现如下提示:
Pleasechooseyourcompilerforbuildingexternalinterface(MEX)files:
Wouldyoulikemextolocateinstalledcompilers[y]/n?
此时键入”y”,按回车;
(c)命令窗口出现如下提示:
Pleasechooseyourcompilerforbuildingexternalinterface(MEX)files:
Wouldyoulikemextolocateinstalledcompilers[y]/n?
y
Selectacompiler:
[1]DigitalVisualFortranversion6.0inC:
\ProgramFiles\MicrosoftVisualStudio
[2]LccCversion2.4inC:
\MATLAB6P5\sys\lcc
[3]MicrosoftVisualC/C++version6.0inC:
\ProgramFiles\MicrosoftVisualStudio
[0]None
此时键入”3”,按回车;选择MicrosoftVisualC++6.0的编译器
(d)命令窗口出现如下提示:
Pleaseverifyyourchoices:
Compiler:
MicrosoftVisualC/C++6.0
Location:
C:
\ProgramFiles\MicrosoftVisualStudio
Arethesecorrect?
([y]/n):
此时键入”y”,按回车;确认选择MicrosoftVisualC++6.0的编译器
(2)mbuild命令设置
(a)运行Matlab,在Matlab的命令窗口(CommandWindow)键入“mbuild-setup”命令后,按回车键,安装Matlab编译器;
(b)命令窗口出现如下提示:
PleasechooseyourcompilerforbuildingstandaloneMATLABapplications:
Wouldyoulikembuildtolocateinstalledcompilers[y]/n?
此时键入”y”,按回车;
(c)命令窗口出现如下提示:
[1]LccCversion2.4inC:
\MATLAB6P5\sys\lcc
[2]MicrosoftVisualC/C++version6.0inC:
\ProgramFiles\MicrosoftVisualStudio
[0]None
此时键入”2”,按回车;选择MicrosoftVisualC++6.0的编译器
(d)命令窗口出现如下提示:
Pleaseverifyyourchoices:
Compiler:
MicrosoftVisualC/C++6.0
Location:
C:
\ProgramFiles\MicrosoftVisualStudio
Arethesecorrect?
([y]/n):
此时键入”y”,按回车,确认选择MicrosoftVisualC++6.0的编译器,编译器设置完成。
3、编写Matlab函数
函数文件sum_prod.m,内容如下:
function[sum,prod]=sum_prod(p1,p2)
sum=p1+p2;%p1与p2的和
prod=p1.*p2;%p1与p2的点乘
该函数完成的是矩阵的求和与点乘的功能,下面将介绍把该代码转换成VC++环境可用的代码的方法。
4、将Matlab函数转成DLL函数
在Matlab7.0的CommandWindow下输入命令:
命令1:
mcc-Wlib:
libsum_prod-Tlink:
libsum_prod.m
或
命令2:
mcc-Wcpplib:
libsum_prod-Tlink:
libsum_prod.m
生成动态链接库DLL,编译完成后,Matlab生成一些文件,其中
libsum_prod.ctf
libsum_prod.dll
libsum_prod.h
libsum_prod.lib
这些文件是我们后面需要用到的。
特别注意:
命令1生成的DLL函数接口的数据类型是mxArray,命令2生成的DLL函数接口的数据类型是mwArray。
5、VC++6.0工程的创建与设置
(1)建立一个名为Test的C++控制台工程,在工程中添加一个名为Test.cpp文件
(2)对VC++6.0,进行以下设置
单击菜单Tools,出现如下菜单
单击Options…菜单项,出现Options对话框,选择Directories标签,在includefiles里面加入:
C:
\MATLAB7\EXTERN\INCLUDE
如下图所示
在Libraryfiles里面加入:
C:
\MATLAB7\EXTERN\LIB\WIN32\MICROSOFT\MSVC60
如下图所
(3)对该工程,进行以下设置
单击菜单Project,出现如下菜单
单击Setting…菜单项,出现ProjectSetting对话框,选择Link标签,在Object/librarymodules:
下面的文本框内容的后面加入mclmcrrt.liblibsum_prod.lib,如下图所示
6、代码编辑及DLL调用
(1)将前面生成的四个文件:
libsum_prod.ctf
libsum_prod.dll
libsum_prod.h
libsum_prod.lib
复制到VC工程所在目录。
(2)在VC++6.0环境中,单击菜单Project,选择AddtoProject菜单项,再单击Files…子菜单项,出现如下图对话框,
将libsum_prod.h加入到当前工程中。
3)当用命令1生成的DLL函数时,在工程文件Test.cpp中添加以下代码:
#include"iostream.h"//输入输出头文件
#include"mclmcr.h"//mxArray类型声明
#include"libsum_prod.h"//DLL头文件
voiddisplay(constmxArray*in,constchar*name);
intmain()
{
//初始化程序
if(!
mclInitializeApplication(NULL,0))
{
fprintf(stderr,"Couldnotinitializetheapplication.\n");
exit
(1);
}
//初始化库
if(!
libsum_prodInitialize())
{
fprintf(stderr,"Couldnotinitializethelibrary.\n");
exit
(1);
}
//声明DLL函数输入输出mxArray对象
mxArray*X,*Y;
mxArray*SUM=NULL,*PROD=NULL;
//给输入mxArray对象分配内存
X=mxCreateDoubleMatrix(2,3,mxREAL);
Y=mxCreateDoubleMatrix(2,3,mxREAL);
doublex[]={1,2,3,4,5,6};
doubley[]={7,8,9,10,11,12};
//给输入mxArray对象赋值
memcpy(mxGetPr(X),x,6*sizeof(double));
memcpy(mxGetPr(Y),y,6*sizeof(double));
//调用DLL函数,注意输入与输出的接口是不同的
mlfSum_prod(2,&SUM,&PROD,X,Y);
//显示mxArray对象
display(SUM,"SUM");
display(PROD,"PROD");
//释放输入输出mxArray对象所占用的内存
//注意输出对象的内存是在调用DLL函数过程中分配的
mxDestroyArray(X);
mxDestroyArray(Y);
mxDestroyArray(SUM);
mxDestroyArray(PROD);
//关闭库和程序
libsum_prodTerminate();
mclTerminateApplication();
return0;
}
//显示矩阵函数
voiddisplay(constmxArray*in,constchar*name)
{
inti,j,r,c;
double*data;
data=mxGetPr(in);
r=mxGetM(in);
c=mxGetN(in);
printf("%s=\n",name);
for(i=0;i { printf("\t"); for(j=0;j printf("%4.2f\t",data[j*r+i]); printf("\n"); } printf("\n"); } 该C++程序运算结果如下图所示 (4)当用命令2生成的DLL函数时,在工程文件Test.cpp中添加以下代码: #include"iostream.h"//输入输出头文件 #include"mclmcr.h"//mwArray类型声明 #include"libsum_prod.h"//DLL头文件 voiddisplay(constdouble*data,constintr,constintc,constchar*name); intmain() { //初始化程序 if(! mclInitializeApplication(NULL,0)) { fprintf(stderr,"Couldnotinitializetheapplication.\n"); exit (1); } //初始化库 if(! libsum_prodInitialize()) { fprintf(stderr,"Couldnotinitializethelibrary.\n"); exit (1); } //声明DLL函数输入输出mwArray对象 mwArrayX(2,3,mxDOUBLE_CLASS); mwArrayY(2,3,mxDOUBLE_CLASS); mwArraySUM,PROD; doublex[]={1,2,3,4,5,6}; doubley[]={7,8,9,10,11,12}; double*sum,*prod; sum=newdouble[6]; prod=newdouble[6]; //给输入mwArray对象赋值 X.SetData(x,6); Y.SetData(y,6); //调用DLL函数 sum_prod(2,SUM,PROD,X,Y); //取出输出数据 SUM.GetData(sum,6); PROD.GetData(prod,6); //显示mwArray对象 //std: : cout<<"SUM="< : endl< : endl;; //std: : cout<<"PROD="< : endl< : endl;; display(sum,2,3,"SUM"); display(prod,2,3,"PROD"); deletesum; deleteprod; //关闭库和程序 libsum_prodTerminate(); mclTerminateApplication(); return0; } //显示矩阵函数 voiddisplay(constdouble*data,constintr,constintc,constchar*name) { inti,j; printf("%s=\n",name); for(i=0;i { printf("\t"); for(j=0;j printf("%4.2f\t",data[j*r+i]); printf("\n"); } printf("\n"); } 该C++程序运算结果如下图所 特别说明: 在C\C++环境中二维数组是“行向量”,如果将下面定义的变量x看成二维数组的话 doublex[]={1,2,3,4,5,6}; 那么x应该是 的矩阵,即 x=[1,2,3; 4,5,6]; 但是,如果将数组首地址x初始化mxArray和mwArray类时,数组x在mxArray和mwArray类中是按“列向量”的形式排列的,即 X=[1,3,5; 2,4,6]; 同理,这里 Y=[7,9,11; 8,10,12]; 因此才能得到上图的结果 mwArray和mxArray有什么区别? 首先,mxArray是MatlabC函数库的结构体,而mwArray是MatlabC++函数库中对mxArray的包装类。 其次,二者的内存管理方式不同。 mxArray的内存管理方式比较松散,由于是C函数库,没有数据封装,必须对临时阵列和约束阵列的概念极为明确,并且须小心地防止内存泄漏(要多写好多代码)。 尽管有自动内存管理机制(mlfEnterNewContext,mlfReleasePreviousContext),仍然要处处调用mlfAssign,麻烦得很。 然而mwArray就好的多,一切交给C++对象去搞定,你只要放心地用就可以了。 不过MatlabC++函数库为了防止频繁内存分配和释放重写了内存分配和释放等函数。 你会发现对于mwArraya,b;a=b;实际上并没有生成两个相同数据块,只是指针,只有发成数据改变时才copy完整数据。 再次,这两个东西各自有一套与之相对应的函数。 函数的返回值类型不同,需要多加注意。 最后,用的时候mxArray要使用指针,而mwArray直接当类对象使。 如果你不是Hardcore级的牛人或具有Hardcore倾向的潜牛人,我强烈建议你使用后者! 举一个简单的例子: 如果你需要计算c=a+b那么两者的区别是这样的: mxArray: voidfun(){ …… doubled_a=1,d_b=2; mxArray*a,*b,*c; mlfEnterNewContext(0,0); mlfAssign(&a,mlfScalar(d_a)); mlfAssign(&b,mlfScalar(d_b)); mlfAssign(&c,mlfPlus(a,b)); …… mlfReleasePreviousContext(0,0); mxDestroyArray(a); mxDestroyArray(b); mxDestroyArray(c); } mwArray: voidfun(){ …… mwArraya,b,c; a=1; b=2; c=a+b; …… } ------------------------------------------------------------------ 另外一个说法: 声明: mxArray: mxArray*a; mwArray mwArraya; 销毁 mxArray mxDestroyArraya; mwArray mwArray类的析构函数自动销毁对象 变量传递 mxArray memcpy(dest_ptr,source_ptr,MAX_SIZE); mwArray mwArrayin1(3,3,mxDOUBLE_CLASS,mxREAL);mwArrayin2(3,3,mxDOUBLE_CLASS,mxREAL);in1.SetData(data,9);in2.SetData(data,9); 比较而言, 1。 mwArray的声明更简洁,不用考虑指针 2。 mwArray不用手动释放内存 建议参考mwArray的帮助信息,推荐使用mwArray: : setData函数来把C++数组数据传递给mwArray对象,从而传递给调用函数。 下面是帮助中给出的一段示例代码: #include"mclcppclass.h" doublerdata[4]={1.0,2.0,3.0,4.0}; doubledata_copy[4]; mwArraya(2,2,mxDOUBLE_CLASS); a.SetData(rdata,4); a.GetData(data_copy,4); 最后,建议大家分阶段调试代码,只是弄清楚错误出在那个阶段: 比如是否已经正确地从用户界面拿到了数据,是否已经正确的创建了mwArray对象,等等。 简单的“运行时间错误”可能和所有这些步骤都有关。 另外,请不要指明让某某人进来看贴,这对于问题没有丝毫帮助,反而导致提问者更晚获得帮助, 我还是怀疑程序在别的地方有问题。 创建和传递mwArray并没有什么特别的。 下面贴上书中第七章例子mccmfc02中的代码,其中创建一个mwArray对象,对应于两个元素的一维数组,然后传递给matlab编译后的函数。 希望能有所帮助。 voidCmccmfc02Dlg: : OnBnClickedButtonTest() { //TODO: Addyourcontrolnotificationhandlercodehere doublefigsize[]={0.0,0.0}; //Getclientareasize CRectclient_rect; GetClientRect(&client_rect); figsize[0]=client_rect.Width(); figsize[1]=client_rect.Height(); //constructaninstanceofmwArrayofthefiguresize mwArraymwFigSize(2,1,mxDOUBLE_CLASS,mxREAL); mwFigSize.SetData(figsize,2); //callthefunction testcopyfigure(mwFigSize); //pastethefigurefromtheclipboardtotheapplication myFig.PasteFigure(); } ———————————————————————————————————————— 不好意思,有点事情没能及时来看贴,请见谅。 下面是m文件 functionPcc(N,d,tar,S,null); %N=30; tar1=tar*pi/180; %d=0.5; Dx=[-(N-1)/2: 1: (N-1)/2]*d; u=-90: 0.1: 90; u1=u*pi/180; ui=null; %ui=[40.5,39.5,39,-39,-38.5,-38]; %ui=[30,31]; nulls=ui*pi/180; v=exp(j*2*pi*Dx.'*sin(u1)); vs=exp(j*2*pi*Dx.'*sin(tar1)); C=[exp(j*2*pi*Dx.'*sin(nulls))]; Wd=tay(30,S); Pc=C*inv(C'*C)*C'; Wo=((Wd.*vs)'*(eye(Nx)-Pc))'; b=Wo'*v; bdb=20*log10(abs(b)/max(abs(b))); figure('visible','off'); %上句以及最后的两句是引用mcctest02中的,不知这样使用是否有误。 plot(u,bdb); axis([-9090-12010]); ylabel('B(dB)') xlabel('\itu') gridon zoomon print-dmeta close(gcf) 下面是c++中调用的程序: UpdateData(true); doublex1=m_Num; doublex2=m_wavelength; doublex3=m_point; doublex4=m_window; doublex5[]={m_null1,m_
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Matlab75a 函数 转换 VC 60 动态 链接 修改