C++Builder下调用Matlab的COM总结

来源:互联网 发布:云计算创始人 编辑:程序博客网 时间:2024/04/30 21:31

C++Builder下调用Matlab的COM总结

 

胡劲松

(浙江大学博士后流动站、宁波保税区博士后工作站,宁波保税区,315800)

 

组件对象模型(简称COM)是windows对象的二进制标准。为WINDOWS提供了统一的,面向对象的,可扩充的通讯协议。这意味着描述一个对象的可执行代码(.dll或.exe文件的代码)可以被其它对象执行。即使两个对象使用不同语言来编写的,他们可以用COM标准来进行通信。Mathworks公司在Matlab6.5中推出了将Matlab中的.m函数编译为COM组件的工具COM Builder,使用这个工具可以方便的制作出想要的COM组件,以供其它支持COM的编程语言调用,实现Matlab和其他编程语言的整合。

下面就一个具体的例子介绍C++Builder5和Matlab6.5通过COM 实现混合编程的具体实现。

1  Matlab编译环境的设置

 

Matlab COM Builder在编译生成COM组件的时候需要借助于外部的编译器。因为并不是所有的编译器都能生成和Microsoft相兼容的COM组件,因此COM Builder只支持下列编译器:

Borland C++ Builder 3

Borland C++ Builder 4

Borland C++ Builder 5

Microsoft Visual Studio 5.0

Microsoft Visual Studio 6.0

Microsoft Visual Studio.NET

Matlab安装了COM Builder(一般在安装Matlab 的时候只要选中COM Builder就可以了)之后,要先设置Matlab COM Builder所使用的外部编译器。可以通过mbuild–setup实现。

Matlab 的Command Window输入命令mbuild–setup,并根据提示选择合适的编译器。笔者使用的是Microsoft Visual Studio 6.0,过程如下:

>> mbuild -setup

Please choose your compiler for building standalone MATLAB applications:

Would you like mbuild to locate installed compilers [y]/n?

Select a compiler:

[1] Lcc C version 2.4 in D:/MATLAB6P5/sys/lcc

[2] Microsoft Visual C/C++ version 7.0 in C:/Program Files/Microsoft Visual Studio .NET

[3] Microsoft Visual C/C++ version 6.0 in D:/Microsoft Visual Studio

[0] None

Compiler: 3

Please verify your choices:

Compiler: Microsoft Visual C/C++ 6.0

Location: D:/Microsoft Visual Studio

Are these correct?([y]/n):

具体的提示会因为不同的情况而变化。

若我们的工作路径在e:/matest下,在Command Window 中输入命令cd('e:/matest');mccsavepath;设置Matlab 为编译器提供的搜索路径, 这些命令只输入一次就可以了。

 

2 使用Matlab COM Builder制作需要的COM 组件

 

所用到的matlab测试文件为plotdata.m,如下:

function [myout]=plotdata(data)

myout=data;

plot(data);

set(gcf,'MenuBar','none');

该函数相当简单,有一个输入变量data和一个输出变量myout,函数只是把输入的数据画图显示,并把输入数据赋值给输出数据,虽然简单,但是已经包含了接口,具有典型性。

Matlab的Command Window中输入命令comtool,启动COM Builder的图形用户界面如图1:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


1 COM Builder主窗口

 

然后使用File->New Project… 建立新的工程,会出现下面的工程设置窗口,如图2。在Component name 中输入你要生成的COM 组件的的名字,例如我们输入名字testout, 最后生成的COM组件的名字就是这个名字加上版本信息。通过add>>Remove按纽可以方便的为这个COM 组件添加和删除类(CLASS)。在这里, 我们为这个组件添加一个类testout。Project version是为了用户方便地管理自己所生成的COM 组件而设置的, 通过这个版本号, 用户可以方便地区分不同时期制作的相同名字的COM 组件。Project directory 是整个工程存放的目录。在Compile Code in里面推荐选择C, 因为C代码性能较好,C++代码可读性好, 因为最后使用的是DLL,因此不需要看中间的代码,所以选择性能较好的C代码。如果要使用Matlab的图形库,那么就要在Compiler options中选中Use Handle Graphics library。选中Builddebug version会生成调试版本的COM组件,调试版本的COM组件在调试的时候如果有错误发生,就会有相应的错误提示信息,可以的方便的定位与错误发生的地方,而不是debug 版本的COM在出错时不会给出任何的错误提示信息。选中Show verbose output可以在编译生成COM组件的时候输出详细的过程信息。在工程创建之后,仍然可以通过菜单Project->Settings… 打开此窗口进行修改。一个COM 组件可以包含许多类( CLASS),添加的方法就是在Project Setting 里面添加。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


2 工程设置窗口

给一个类添加一个方法非常地简单:先用选中所要对其进行操作的类,然后使用菜单Project->Add File… 或者按纽Add File添加现成的( 预先编写好的)文件就可以了。注意* .m文件不能是脚本文件, 只能是函数文件。把plotdata.m文件加入,类添加了一个简所有函数添加完毕之后, 就可以使用菜单Build->COM Object 或者按纽Build进行编译了。编译完毕之后会在工程文件夹下生成两个文件夹:一个是src,里面存放的是一些中间文件; 一个是distrib,里面就是我们想要的东西。在编译完毕之后, Matlab 会自动组成生成的component, 我们可以使用菜单Component->Component Info… 将系统注册表里面有关于testout_1_0.dll 的详细信息调出来看一看有关生成的component的信息。

 

 

 

 3 C++Builder中使用生成的COM组件

在使用组件之前一定要先对组件进行注册, 而注册工作Matlab已经替我们完成了。点击C++Builder的Project->Import Type Library…,出现如图3所示的界面,在上面的窗口中找到testout 1.0 Type Library[Version 1.0],然后点击Install…按钮,

 

 

 

 

 

 

 

 

 

 

 

 

 

 

3 安装COM组件

 

testout控件

 

 

 

 

 


4 testout控件

 

就在AxtiveX控件页按装了testout控件,如图4所示。建立一个工程文件project1,在Form上放置一个testout控件和一个按钮控件,如图5所示。双击按钮,然后添加如下的代码:

 

void __fastcall TForm1::Button1Click(TObject *Sender)

{

double src[100];//传入数据数组;

double outp[100];//传出数据数组;

 

SAFEARRAY InSafeArray;//用于传入的安全数组;

 

TVariantInParam data;//传入COM的变体;

TVariant myout;//传出COM的变体;

 

for(int i=0;i<100;i++)//传入数据赋值;

{

src[i]=cos(i);

}

 

//设置输入安全数组;

InSafeArray.cDims=1;//数组为一维;

InSafeArray.fFeatures=FADF_AUTO;//分配在本应用的堆上;

InSafeArray.cbElements=sizeof(double);//数组元素的大小为double的大小;

InSafeArray.rgsabound[0].lLbound =0;//数组下边界为0;

InSafeArray.cLocks=1;

InSafeArray.rgsabound[0].cElements=100;//数组有100个元素;

InSafeArray.pvData=src;//数组引用src指针;

 

data.SetSAFEARRAY(&InSafeArray);//传入COM的变体设置安全数组;

data.vt=VT_R8|VT_ARRAY;//变体为数组类型,数组为double类型;

 

testout1->plotdata(1,&myout,data);//调用com的方法,第一个为输出的数目,第二个为

//输出的变体,第三个为输入com的数据变体;

 

memcpy(outp,myout.parray->pvData,100*sizeof(double));//把输出变体的数据拷贝到

//传出数据数组里;

 

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


5 建立工程Project1

程序中src数组是保存传入COM控件的数据,outp数组是保存从COM控件传出的数据,这样能实现应用程序和COM的数据接口。本代码把100点的余弦数据传入COM控件,然后控件负责画图,把数据传出来。因为COM不支持指针,所以采用安全数组类型SAFEARRAY的变量传递数据给COM控件。运行程序,点击按钮,出来的运行界面如图6所示,可见与在matlab环境下完全一样。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


6 程序运行界面

 

4 COM组件的打包与程序的发布

 

程序开发完毕就要发布, 对于要使用的的COM 组件可以使用Matlab的COM Builder进行打包。具体的操作是通过菜单Component->Package Component完成的。在distrib文件夹下会生成一个自解压文件testout.exe,通过运行它实现必要的动态链接库的安装和COM 组件的注册,按照提示就可以了。主要操作有两个:一个是输入解压目录,一个就是设置系统的搜索路径(path)。需要注意的问题就是输入的文件夹目录不能包含中文(真是遗憾,毕竟这不是国人开发的)。大功告成,可以运行程序了。

 

 

 

 

 

原创粉丝点击