以下讨论是在MATLAB7.0软件和vc++6.0软件环境中进行:
一、将MATLAB的.m文件编译成.exe文件,实现MATLAB与Visual Basic语言的混合编程
1、将 \MATLAB7\toolbox\compiler\deploy\matlabrc.m 中的81行 set_param(0,'PaperType',defaultpaper)
和82行set_param(0,'PaperUnits',defaultunits)
注释掉,或者干脆删掉,否则,在没有安装MATLAB的机子上运行MATLAB与VisualBasic语链世培言混合编成的程序时,会出现:“Undefinedcommand/function 'set_param'”的错误。
2、在Matlab7 的命令窗口运行下列命令:rehash toolboxcache
完成工具箱加载和更新。
3、在Matlab7 的命令窗口运棚唯行下列命令:
Mcc –m ***.m
将MATLAB的.m文件(M文件必须以Function开始,即必须是函数文件)编译成.exe文件,将编译生成的.ctf文件和.exe文件拷贝到VB工程的目录中,他们是脱离matlab环境运行必返雀需的文件;
4、在VB工程中用下列语句对MATLAB的.m文件编译成的.exe文件进行调用:
lTask = Shell("rt2.exe",vbHide)
hProc= OpenProcess(PROCESS_QUERY_INFORMATION, False, lTask)
IflTask = 0 Then MsgBox "程序执行失败"
Do
GetExitCodeProcess hProc, lExit
DoEvents
LoopWhile lExit = STILL_ACTIVE
5、将VB工程进行打包,打包时,要将在MATLAB中编译生成的.ctf文件和.exe文件添加到VB工程包中,他们是脱离matlab环境运行必需的文件;
6、将打包好的VB工程安装包拷贝到客户计算机中,并将matlab7\toolbox\compiler\deploy\win32下的MCRInstaller.exe程序也一起拷贝到客户计算机中。
7、在客户计算机中,运行程序:MCRInstaller.exe,将matlab compiler runtime安装到客户计算机中。注意:安装目录必须位于它所在的文件夹;
8、运行VB工程安装包中的setup程序,进行VB工程的程序安装;
至此,在客户机中,即可正常运行MATLAB与Visual Basic语言混合编成的程序。
注意事项:
1、在VB工程所在目录中,不能有其它的.dll文件存在,否则在客户机中运行MATLAB与Visual Basic语言混合编成的程序时,会出现下列错误提示:
“Warning:Failed to startthe Java Virtual machine.”
“Warning:Disabling Javasupport.”
“Undefined function orvariable ‘matlabrc’.”
二、将MATLAB的.m文件编译成.dll文件,实现MATLAB与Visual Basic语言的混合编程
1、将 \MATLAB7\toolbox\compiler\deploy\matlabrc.m 中的81行 set_param(0,'PaperType',defaultpaper)
和82行set_param(0,'PaperUnits',defaultunits)
注释掉,或者干脆删掉,否则,在客户机中运行MATLAB与Visual Basic语言混合编成的程序时,会出现:“Undefined command/function 'set_param'”的错误。
2、在Matlab7 的命令窗口运行下列命令:rehash toolboxcache
完成工具箱加载和更新。
3、安装vc++6.0软件,为Matlab编译器的安装和配置做准备;
4、在Matlab7 的命令窗口运行下列命令:
mbuild –setup
对Matlab的编译器进行安装和配置;
5、在Matlab中创建COM组件
用Matlab COM生成器创建COM组件,包括4个步骤,即创建工程、管理m文件、生成组件、打包和分发组件。
在Matlab中创建COM组件步骤如下:
(1) 创建工程。在Matlab命令窗中键入comtool命令,调用Matlab编译器,打开Matlab COM Build主窗口。在该窗口中,选择File→New Project,创建一个新的工程,在此对话框中对新工程进行设置,输入组件名和类名,选择合适的编译器。
(2) 管理m文件。单击“AddFile”按钮,添加编写好的M函数文件(M文件必须以Function开始,即必须是函数文件)。
(3) 生成组件。使用Build--àCom object菜单,创建COM组件,将MATLAB的.m文件编译成.dll文件。
(4)打包和分发组件:编译成功并通过测试后,就可以把有关文件打包和分发给目标器。单击 “Component”→”Package Component”,创建自解压可执行程序。注意:在使用Component--àPackageComponent菜单,生成.exe文件时,要将“includeMCR”前的选择框选中,使生成的.exe文件中能包含MCRInstaller.exe程序。
6、将编译生成的.ctf文件和.dll文件以及.exe文件拷贝到VB工程的目录中;
7、创建VB工程并调用COM组件新建“标准EXE”工程,进入VB编程环境,在“工程”菜单中单击“引用”选项, 在列表中选中第5步中生成的这些组件,以及添加MWComUtil 7.0 Type Library,单击“确定”按钮。
在VB工程引用这些组件后,需按照以下步骤来调用Matlab文件:
Dim rt2 As rt2_1.rt2_1class '声明一个COM组件
Set rt2 = New rt2_1.rt2_1class
Call rt2.rt2 '执行rt2_1_1_0.dll文件
8、将VB工程进行打包,打包时,要将在MATLAB中编译生成的.ctf文件和.dll文件以及.exe添加到VB工程包中;
9、在客户计算机中,运行第5步中生成的.exe程序,对第5步中生成的.dll动态链接库进行注册,并自动运行MCRInstaller.exe程序,将matlab compiler runtime安装到客户计算机中。
10、将打包好的VB工程安装包拷贝到客户计算机中,运行VB工程安装包中的setup程序,进行VB工程的程序安装;
至此,在客户机中,即可正常运行MATLAB与Visual Basic语言混合编成的程序。
注意事项:
1、VB编译生成的MATLAB与Visual Basic语言混合编成的exe应用程序不能简单的移植,必须要打包,在打包时应带上dll文件,然后将打包好的VB工程安装包拷贝到客户机中,运行VB工程安装包中的setup.exe安装程序,进行VB工程的安装,VB工程安装完成后,再在客户机中,运行第5步中生成的.exe程序,就可以避免出现下列各种错误提示:
(1)“Warning:Failedto start the Java Virtualmachine.”
“Warning:Disabling Javasupport.”
“Undefined function orvariable ‘matlabrc’.”
(2)“Automation错误”或者“自动化错误”
(3)“运行时错误’429’:ActiveX部件不能创建对象”
(4)“MCR instance isnot available.”
2、在VB工程所在目录中,除了包含第5步中生成的.dll动态链接库文件外,不能有其它的.dll文件存在,否则在客户机中运行MATLAB与Visual Basic语言混合编成的程序时,会出现下列错误提示:
“Warning:Failed to startthe Java Virtual machine.”
“Warning:Disabling Javasupport.”
“Undefined function orvariable ‘matlabrc’.”
3、如果直接将Vb工程程序拷贝到客户机中,而不是通过安装Vb工程程序,来运行MATLAB与VisualBasic语言混合编成的程序时,会出现:“Automation错误”或者“自动化错误”的错误提示,这时可以通过下列方法之一解决:
(1)在客户机中运行第5步中生成的.exe程序,对第5步中生成的.dll动态链接库进行注册,就可以解决“Automation错误”或者“自动化错误”引起的程序运行异常。
(2)在客户机中直接运行regsvr32.exe程序,对第5步中生成的.dll动态链接库进行注册,也可以解决“Automation错误”或者“自动化错误”引起的程序运行异常。
4、如果在客户机中,没有运行第5步中生成的.exe程序,对第5步中生成的.dll动态链接库进行注册,那么在客户机中运行MATLAB与Visual Basic语言混合编成的程序时,就会出现:“运行时错误’429’:ActiveX部件不能创建对象”的提示,或者出现:“Automation错误”或者“自动化错误”的错误提示。
5、如果在客户机中运行MATLAB与Visual Basic语言混合编成的程序时,出现:“MCR instance isnot available.”的错误提示时,可以通过将打包好的VB工程安装包拷贝到客户计算机中,运行VB工程安装包中的setup程序,进行VB工程的程序安装,就可以解决这种错误。
在C++Builder中调用Matlab工具箱函数,有两种实现方式。一种是基于Matlab环境支持,通过必要的设置实现;笔者在本刊上曾撰文对这种方式进行了专门的阐述。另一种则是完全脱离Matlab环境,通过动态连接库方式实现对Matlab工具箱函数的调用,这可以通过一种开发平台Mediva来实现。相对来说,前者的限制因素较多,而后者则较为方便灵活。
一、Mediva软件平台
Mediva是Mathtools公司推出的一种Matlab编译开发软件平台,提供对Matlab程序文件(M文件)的解释执行和开发环境支持。该软件有为Borland C++、Visual Basic和Dephi等编程语言开发的不同版本,目前其版本已经到了4.5版。软件大小仅6.5M,可以通过访问其站点www.mathtools.com免费下载试用一个月。 Mediva软件平台本身的功能相当强大,提供近千个Matlab的基本功能函数,通过必要的设置,就可以直接实现与C++的混合编程,而不必再依赖Matlab;同时,Mediva还提供编译转换功能,能够将Matlab函数或编写的Matlab程序转换为C++形式的DLL,从而实现脱离Matlab环境对Matlab函数和过程的有效调用,这样就有可能实现对Matlab强大的工具箱函数的利用。
Mediva的缺点是C++与Matlab混合编写的应用软件必须携带必要的DLL,从而增大了软件的体积(约4M),同时也不能对所有的Matlab函数提供支持,例如采用类库进行设计的部分函数。但尽管如此,对于控制系统计算机设计、分析的工作来说,Mediva仍不失为一个好的工具。
由于利用Mediva将Matlab工具箱函数转换成DLL的内容较多,限于篇幅本文在此仅给出对Matlab函数直接调用的实现,而将另撰文阐述DLL的实现。
二、C++Builder直接调用Matlab函数
本文假设已经安装了Mediva软件或已经得到必要的两个动态连接库mdv4300.dll和ago4300.dll。
Mediva提供的近千个Matlab基本功能函数,都可以在C++Builder中直接调用。这些函数包括基物亩本的 *** 作、命令、I/O、线性代数、位图、控制等,基本上可以满足我们的一般需要。当然其的优点就是可以直接在C++Buider中直接调用而不必耐蚂手考虑安装庞大的Matlab。
其实现方式和步骤如下:
1.Lib文件的生成
在Dos下用C++Builder中的Implib.exe,通过如下命令生成mdv4300.lib: implib mdv4300.lib mdv4300.dll
将上述两个DLL文件和此Lib文件拷贝到当前目录下。
2.实现与Matlab的混合编程
Matlab.h包含了Mediva中昌嫌所有类型、常量、函数的说明和定义,必须将此头文件放于程序的第一行。Mediva给出的Matlab函数形式并不特殊,如绘线函数Plot,在Mediva中说明为:Mm DLLI plot(cMm varargin);varargin与Matlab 中的意义是一样的,与输入变量的个数相对应。所有可以直接使用的函数都在Matlib.h头文件中定义,而在mdv4300.dll中实现。
但在C++Builder中使用Mediva提供的Matlab函数的格式,与Matlab编程稍有不同,这主要体现在C++中必须进行必要的说明上。例如我们要用绘线函数Plot来绘制数组x[100]的红色图线。在Matlab中调用为Plot(x,'r');在C++中调用则为:Plot(CL(x),TM("r")),其中CL是一个关键字,是多变量输入时所必须使用的,用以指明调用的变量;而TM则指明,这是一个字符。
下面我们给出一个示例程序,其功能是对一个1024点的输入数组进行FFT 变换,并绘制变换后频谱实部的火柴杆图,最后将原数据和变换后的数据写入数据文件中。
#include "matlib.h"
//必须包含的头文件
#include vcl.h >
#pragma hdrstop
#include "TryMatcomU.h"
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1
__fastcall TForm1::TForm1(Tcomponent* Owner)
: Tform(Owner)
{
}
void __fastcall TForm1::Button1Click(Tobject *Sender)
{
int k=0
initM(MATCOM_VERSION) //必须进行的初始化
Mm cur1,cur2 //定义变量
cur1=zeros(128) cur2=zeros(128) //变量初始化
for(k=1k<=128k++)
cur1.r(k)=randM() //生成一个随机数列
figure(1)
plot(cur1)//图形显示该数列
cur2=fft(cur1,128) //做128点fft变换
figure(2)//绘制fft变换后实部的火柴杆图,注意此处多变量输入的格式
stem((CL(cur1),real(cur2),TM("r")))
fid=fopen(filename,mode,format) opens
exitM() //退出调用
}
如果完全使用C++来实现本程序的工作,其代码将超过300行!由此可以看出,C++Builder与Matlab函数的混合编程可以给我们带来多么大的方便!
Java和matlab混合编程
如果用Matlab和java混合编程开发Windows的应用程序则可以实现优势互补,缩短开发时间,降低程序设计的复杂度。同时程序可以脱离Matlab环境独立运行,在数袜工程计算和教学实践中都具有实际意义。
1.使用java调用Maltab函数的基本方法是:通过Java Builder实现Java调用Matlab。在Java环境中直接调用Matlab所生成的Jar包。
下面以在Java中产生任意维数的魔方矩阵,计算任意矩阵的特征向量和特征值,对两组数据进
行拟合并绘制拟合曲线三个实例来说明通过Java
Builder实现Java调用Matlab的过程。传统的纯Java编程实现上述实例非常复杂,甚至很难完成。这一问题在Matlab中只需要调用几个
函数即可完成。
1.1、将Matlab函数包装成Java类
首先在Matlab中编写三个M文件:
Eig.m
function [v,d]=Eig(input)
format long
[v,d]=eig(input)
End
Magic.m
function f =Magic( input )
f=magic(input)
end
Plot.m
function Plot(x,y )
p=polyfit(x,y,3)
t=min(x):max(x)/100:max(x)
s=polyval(p,t)
plot(x,y,'*',t,s)
title('数据拟合结果')
xlabel('x')
ylabel('y')
end
其次,在Matlab中新建一个Deployment
Project,名称为MyProject.prj,类型为Java
package。在Project中新建三个Class,分别为GetEig,GetMagic,PolyFit。将
Eig.m,Magic.m,plot.m分别添加到上述Class中。之后点击Builder the project,等待编译成功即可。
1.2、在Java中调用Matlab函数
新建一个Java类JavaMatlab,并引入相关的包。
import com.mathworks.toolbox.javabuilder.*//引入Matlab相关包
import MyProject.*//引入建立的包及类羡肆
调用时Java与Matlab之间的参数传递薯派激需要通过MWNumericArray完成。具体的调用代码如下:
package org.genius.ExpandJava
import MyProject.*
import com.mathworks.toolbox.javabuilder.*
public class JavaMatlab {
public static void main(String[] args) {
MWNumericArray a = null// 用于保存矩阵
MWNumericArray ax = null// 用于保存矩阵
MWNumericArray ay = null// 用于保存矩阵
Object[] result = null// 用于保存计算结果
GetEig getEig = null
GetMagic getMagic=null
PolyFit polyFit=null
int r = 4// 魔方矩阵维数
int array[][]={{50,-20,0},{-20,80,60},{0,60,-70}}
double x[]={0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1}
double y[]={-0.447,1.978,3.28,6.16,7.08,7.34,7.66,9.56,9.48,9.3,11.2}
try {
//产生魔方矩阵并打印
a = new MWNumericArray(r, MWClassID.DOUBLE)
getMagic = new GetMagic()
result = getMagic.Magic(1,a)
System.out.println("产生的四维魔方矩阵:")
System.out.println(result[0])
MWArray.disposeArray(result)
//计算所给矩阵的特征向量和特征值并打印结果
a = new MWNumericArray(array, MWClassID.DOUBLE)
getEig = new GetEig()
result = getEig.Eig(2, a)
System.out.println("原始矩阵:")
System.out.println(a.toString())
System.out.println("得到的特征向量:")
System.out.println(result[0])
System.out.println("得到的特征值:")
System.out.println(result[1])
MWArray.disposeArray(result)
ax = new MWNumericArray(x, MWClassID.DOUBLE)
ay = new MWNumericArray(y, MWClassID.DOUBLE)
polyFit = new PolyFit()
result=polyFit.Plot(ax,ay)
polyFit.waitForFigures()
} catch (Exception e) {
System.out.println("Exception: " + e.toString())
}
finally {
// 释放本地资源
MWArray.disposeArray(a)
MWArray.disposeArray(ax)
MWArray.disposeArray(ay)
MWArray.disposeArray(result)
getEig.dispose()
getMagic.dispose()
polyFit.dispose()
}
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)