C++ Builder与Matlab殽杂编程的实现
副标题#e#
在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文件拷贝到当前目次下。
#p#副标题#e#
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=1;k< =128;k++)
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函数的殽杂编程可以给我们带来何等大的利便!
3.变量内部状态/数据的调查要领
#p#分页标题#e#
Mediva利用的所有变量均界说为Mm范例。假如在C++Builder中调查Mm范例变量的内部状态/数据,要稍贫苦一些。但在调试措施时,这又是不行制止的一步,这里举例给出变量调查的要领。
譬喻对上面生成的cur2数罗列办调查,
*cur2.pr 0.1892 cur2(1)的实部
*cur2.pi 0.0013 cur2(1)的虚部
三、C++Builder挪用Matlab东西箱函数转换后的DLL
1.Matlab函数向DLL的转化
Mediva软件提供了将Matlab函数转换为DLL的成果,很是利便。但需要留意的是:
1.Matlab5.0以上版本,所有带有tf类的函数均无法转换;
2.Matlab4.2以下版本,大都函数可以或许转换,但转换后大多不能直接利用,而必需加以处理惩罚。
MATCOM V4.3中把含有输入参数的M文件转换成DLL时,生成的DLL无法挪用.以.M为例
function [x1,x2]=flower(x3)
MATCOM生成的FLOWER.CPP和FLOWER.H中声明为:
Mm flower(Mm x3, i_o_t, Mm& x1__o, Mm& x2__o)
{
begin_scope
x3.setname("x3");
…
}
Mm flower(Mm x3);
Mm flower(Mm x3, i_o_t, Mm& x1__o, Mm& x2__o);
而生成的G_FLOWER.CPP声明为:
—- void DLLX _stdcall flower_1_1(Mm** in01, Mm **out01)
—- void DLLX _stdcall flower_1_2(Mm** in01, Mm **out01, Mm **out02)
—- 个中对付in01的说明是不正确的.应按如下修改。然后,按如下MAKE文件举办编译
#
# MATCOM makefile
#
all: flower.dll
g_flower.obj: g_flower.cpp
bcc32 -c -Id:\matcom43\ -WD -Id:
\matcom43\lib -H=matlib.csm -a4
-5 -eg_flower.obj g_flower.cpp
flower.dll: flower.obj g_flower.obj
bcc32 -Ld:\matcom43\ -WD -Id:
\matcom43\lib -H=matlib.csm -a4 -5 -eflower.dll
@flower.rsp d:\matcom43\lib\mdv4300b.lib
在CPP中挪用这个函数之前,必然要先给in01分派空间。
#include "matlib.h"
#pragma hdrstop
#include "flower.h"
#define WIN32_LEAN_AND_MEAN
#include < windows.h >
#include "matlib.h"
#pragma hdrstop
extern "C" {
void DLLX _stdcall flower_1_1(Mm in01, Mm **out01) {
*out01=new Mm();
//*in01=new Mm();
**out01=flower(in01);
exitM();
}
void DLLX _stdcall flower_1_2(Mm in01, Mm **out01, Mm **out02) {
*out01=new Mm(); *out02=new Mm();
//*in01=new Mm();
flower(in01, i_o , **out01, **out02);
exitM();
}