基于MATLAB R2009a 的COM组件与VC编程体会 Step by Step

独自摸索了一天时间,终于将MATLAB COM组件调用过程弄清楚了,将体会总结一下,以供大家分享。

第一步:编写m文件,测试正确性

编写m文件,m文件必须要有函数function,如:

function [ab1b2b3b4]=textMATLABCOM(z,v)

其中a,b1,b2,b3,b4均为返回值,二维数组。zv为输入值,二维数组。

function [a b1 b2 b3 b4]=textMATLABCOM(z,v)

z2=zeros(1,0);

z3=zeros(1,0);

v2=zeros(1,0);

v3=zeros(1,0);

z2=z(1,:);

z3=z(2,:);

v2=v(1,:);

v3=v(1,:);

 

a=z2;

b1=z3;

b2=v2;

b3=v3;

b4=z;

测试文件:

z=[1 2 3 4 5; 6 7 8 9 10];

v=[2 3 4 5 6; 6 7 8 9 3];

[a b1 b2 b3b4]=textMATLABCOM(z,v);

a

b1

b2

b3

b4

MATLAB运行结果:

a =     1     2    3     4     5

b1 =     6     7    8     9    10

b2 =     2     3    4     5     6

b3 =     2     3    4     5     6

b4 =     1     2    3     4     5    6    7     8     9   10

第二步:编译m文件,生成dll

保存该函数,并调用deploytool工具,然后新建工程,注意:工程类别为MATLAB Builder NE-------Generic COM Component。工程命名为test,如下图所示。


工程建好之后需要添加m文件,将textMATLABCOM.m添加到test.prj中。


编译工程(注:在初装matlab时,需要运行mbuilder –setup命令,选择编译器为VC),结果显示如下图,则表示编译成功。


在工程文件夹下面生成了两个文件夹:distrib和src,其中distrib中包含dll文件,src中包含h和c文件以及dll文件,这里面的dll文件都在编译过程中由matlab自动进行了注册。


第三步:调用dll文件,实现VC应用

1、 新建一个MFC项目testcom,选择dialog based项。界面为:

 

2、 通过matlab com组件生成必备的c和h文件

首先打开Tools--->OLE/COMObject Viewer,在左列中选择TypeLiberaries,找到对应的test项,双击打开,可以发现里面对testMATLABCOM函数接口进行定义了,如下图所示。


然后点击保存图标,将文件另存为.h文件以及.c文件,可以在src文件夹中发现如下两个文件:


需要注意的是:1、在安装VC的时候,需要让VC自动注册环境变量,否则无法生成这两个文件,并提示出错。2、在另存为这两个文件的时候,选择的目录最好用盘符根目录,在本例中选择的C盘目录,否则会不提示错误,但是找不到生成的文件的问题!

 

3、 VC程序调用matlab com的配置

将dll、h、c文件都拷贝到工程目录testcom下面,并将test_1_0.c与test_1_0.h文件添加到工程文件中。同时还要拷贝如下文件:mwcomtypes.h,mwcomutil.dll, mwcomutil.h文件,并将mwcomtypes.h以及mwcomutil.h文件添加到工程。

在stdafx.h中添加如下头文件:

#include <comdef.h>

#include <atlbase.h>

#include "mwcomtypes.h"

#include "test_1_0.h"

#import "mwcomutil.dll"raw_interfaces_only

#include "mwcomutil.h"

其中,mwcomtypes.h位于test工程的src目录下,mwcomutil.h文件位于C:\ProgramFiles\MATLAB\R2009a\extern\include\win32目录下,mwcomutil.dll文件位于C:\Program Files\MATLAB\R2009a\bin\win32目录下。



配置完成之后,VC工程的文件列表如下图所示:


此时,已经完成了对matlabcom组件调用的初步配置,接下来的工作就是编写源代码了。

 

4、 源代码编写

首先在testcom.cpp文件中的BOOL CTestcomApp::InitInstance()函数中添加如下代码:

       if(CoInitialize(NULL)!=0)

       {

              AfxMessageBox("初始化COM支持库失败!");

              exit(1);

       }

该代码提供对COM组件的初始化工作。截图如下所示:


然后在testcomDlg.cpp文件中定义ITest变量ite.并在对应的函数体中添加如下代码:

ITest *pTe;

……

       //初始化MATLAB COM组件

       pTe=NULL;

       if(FAILED(CoInitialize(NULL)))

       {

              AfxMessageBox("不能够初始化Test COM组件!");

       }

       HRESULThr2=CoCreateInstance(LIBID_test,NULL,CLSCTX_ALL,IID_ITest,(void**)&pTe);

       if(FAILED(hr2))

       {

              AfxMessageBox("不能创建Test COM组件实例!");

       }

至此,有关matlabcom的程序代码配置部分已经完成,接下来进行com接口调用工作。

代码如下:

       //接口调用部分

       doublez[2][5]={ {1,2,3,4,5},{6,7,8,9,10} };

       doublev[2][5]={ {2,3,4,5,6},{6,7,8,9,3} };

 

       VARTYPEvt=VT_R8;

       SAFEARRAYBOUNDsab[2];

       sab[0].cElements=7;

       sab[0].lLbound=0;

       sab[1].cElements=7;

       sab[1].lLbound=0; 

 

       SAFEARRAY*pz=SafeArrayCreate(vt,2,sab);

       SAFEARRAY*pv=SafeArrayCreate(vt,2,sab);

 

       if(NULL==pz|| NULL==pv )

       {

              AfxMessageBox("不能创建SAFEARRAY数组!");

              return;

       }

 

       longDemen[2];

       for(longi=0;i<=1;i++)

       {

              for(longj=0;j<=5;j++)

              {

                     Demen[0]=i;

                     Demen[1]=j;

                     HRESULThre=SafeArrayPutElement(pz,Demen,&z[i][j]);

                     HRESULThre1=SafeArrayPutElement(pv,Demen,&v[i][j]);

                     if(FAILED(hre)|| FAILED(hre1))

                     {

                            AfxMessageBox("数组赋值失败!");

                            return;

                     }

              }

       }

 

 

       VARIANTzo,vo,a,b1,b2,b3,b4;

 

       VariantInit(&zo);

       VariantInit(&vo);

       VariantInit(&a);

       VariantInit(&b1);

       VariantInit(&b2);

       VariantInit(&b3);

       VariantInit(&b4);

 

       zo.vt=VT_ARRAY|vt;

       vo.vt=VT_ARRAY|vt;

 

       zo.parray=pz;

       vo.parray=pv;

 

   /*virtual  [helpstring][id]  HRESULT STDMETHODCALLTYPE textMATLABCOM(

        //[in]  long nargout,

        //[out][in]  VARIANT __RPC_FAR *a,

        //[out][in]  VARIANT __RPC_FAR*b1,

        //[out][in]  VARIANT __RPC_FAR*b2,

        //[out][in]  VARIANT __RPC_FAR*b3,

        //[out][in]  VARIANT __RPC_FAR*b4,

        //[in]  VARIANT z,

        //[in]  VARIANT v) = 0;*/

       pTe->textMATLABCOM(5,&a,&b1,&b2,&b3,&b4,zo,vo);

 

       //获取数据

       CStringstr1="";

       CStringstr2="";

       for(intj=0;j<5;j++)

       {

              str1.Format("%f",*((double*)a.parray->pvData+j));

              str2+=str1;

              str2+="   ";

       }

       AfxMessageBox(str2);

运行结果为:


正是matlab中变量a的返回值。将代码做如下改变:

       //获取数据

       CStringstr1="";

       CStringstr2="";

       for(intj=0;j<5;j++)

       {

              str1.Format("%f",*((double*)b1.parray->pvData+j));

              str2+=str1;

              str2+="   ";

       }

       AfxMessageBox(str2);

运行结果为:


正是matlab中b1的返回值。

后续不再测试,至此,整个调用matlabcom的过程完成!

matlab程序发布过程,将在下面的文章中介绍。


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值