分享
 
 
 

基于ole的VC和matlab混合编程方法

王朝vc·作者佚名  2006-05-23
窄屏简体版  字體: |||超大  

基于ole的VC和matlab混合编程方法

作者:李立新

运行环境:VC++ 6.0 MATLAB6.5 Windows XP

此方法的实现是在网上各位前辈的基础上完成的。特别是参考了哈工大振动论坛上的一篇文章,现在,就具体谈一下怎么把一个M文件或MEX文件,做成可以脱离MATLAB环境的COM组件,并且被VC++调用。

1. 首先,设置合适的编译器。在MATLAB命令窗口里敲:mbuild –setup,完成编译器的设置。

>>mbuild –setup

Please choose your compiler for building standalone MATLAB applications:

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

Select a compiler:

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

[2] Microsoft Visual C/C++ version 6.0 in C:\Program Files\Microsoft Visual Studio

[0] None

Compiler: 2

Please verify your choices:

Compiler: Microsoft Visual C/C++ 6.0

Location: C:\Program Files\Microsoft Visual Studio

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

The default options file:

"C:\Documents and Settings\lilixin\Application Data\MathWorks\MATLAB\R13\compopts.bat"

is being updated from D:\MATLAB6P5\BIN\WIN32\mbuildopts\msvc60compp.bat...

--> "D:\MATLAB6p5\bin\win32\mwregsvr D:\MATLAB6p5\bin\win32\mwcomutil.dll"

DllRegisterServer in D:\MATLAB6p5\bin\win32\mwcomutil.dll succeeded

--> "D:\MATLAB6p5\bin\win32\mwregsvr D:\MATLAB6p5\bin\win32\mwcommgr.dll"

DllRegisterServer in D:\MATLAB6p5\bin\win32\mwcommgr.dll succeeded

Installing the MATLAB Visual Studio add-in ...

Updated C:\Program Files\Microsoft Visual Studio\common\msdev98\template\MATLABWizard.awx

from D:\MATLAB6P5\BIN\WIN32\MATLABWizard.awx

Updated C:\Program Files\Microsoft Visual Studio\common\msdev98\template\MATLABWizard.hlp

from D:\MATLAB6P5\BIN\WIN32\MATLABWizard.hlp

Updated C:\Program Files\Microsoft Visual Studio\common\msdev98\addins\MATLABAddin.dll

from D:\MATLAB6P5\BIN\WIN32\MATLABAddin.dll

Merged D:\MATLAB6P5\BIN\WIN32\usertype.dat

with C:\Program Files\Microsoft Visual Studio\common\msdev98\bin\usertype.dat

2. 设置系统路径。我的电脑-属性-高级-环境变量-系统变量-Path选项,增加以下路径:

头文件:

d:\MATLAB6p5\extern\include;

库:

d:\MATLAB6p5\extern\lib\win32\microsoft\msvc60;

DLL:

d:\MATLAB6p5\bin\win32

3. 做一个简单的M函数(只能是函数不能是文件)。文件名和函数名一致。运行并测试此文件的正确性。

function [out]=arraytest(A)

out=det(A);

B=[A(1,1),A(1,2),A(2,1),A(2,2)]%本来是plot(A),刚开始没能把数据传递好,做了个B阵,做测试用的,

%因为com做好了,就没有改了,要不有很多垃圾

plot(B);

4. 在命令窗口敲comtool,出现com组件builder。选择FILE选项-New Project选项。出现以下界面。

Component name选项:设置com组件的名称,注意不要和上面添加的m文件重名。

Class name选项:设置类名称MyArraytest。一般将鼠标点击空白位置,系统会自动生成类名。

Project version选项:版本号。系统默认为1.0,将来要修改或添加其他函数时,可以修改此选项为2.0,3.0等。

Project directory选项:工程所在目录。

Complier options选项:编译器配置选项,全部选中。

最后单击OK。系统会出现对话框,问你是否创立工程目录,你选YES。

5. 单击Project Files-plotclass-M-files,然后选中comtool菜单Project-Add File选项,添加上面写好的plot_test M函数,当然,可以按需要添加更多的M或MEX函数。

6. 单击Build按钮,选中Com Object选项,这时com-builder会帮你自动编译连接该组件,生成所需要的头文件,源文件,接口描述文件,动态连接库文件,等等。在右侧Build Status显示框里给出了编译的过程和信息。在菜单Component-Component Info里有关于接口、类、库的信息。在d:\MATLAB6p5\work\Myarraytest文件夹里,出现了两个子文件夹,distrib和src,这是我们VC中需要用到的文件、库、资源、接口等。在src\plot_idl_i.c中,有关于com类和com接口的GUID。其中CLSID(类的GUID)在VC编程中需要用到。别急,还有一步打包发布。选择Component-Package Component,系统就会自己帮你打包了。打包文件在distrib文件夹中有Myarraytest可执行文件。拷贝d:\MATLAB6p5\work\Myarraytest文件夹下所有文件,在另外一个机器上,双击Myarraytest可执行程序,注册com组件,。你的程序,就可以在其他机器上执行了。

7. 打开VC++编译器,选择文件-新建-工程-MFC(exe)-命名(newoletest)-对话框-完成(曾经做个几个测试程序,没成功,名字可以自己写)。删除确定和取消按钮,新建一个按钮,我直接使用了ok按钮,删除了取消,把ok按钮中原来的程序删掉了。

8. 打开类向导,在 Add Class选项内,选中From a typed library,进入d:\MATLAB6p5\work\Myarraytest\src文件夹,选中myarraytest_idl.tlb文件,点击打开,OK。

这时一个COM类便加入进来了,查看一下为IMyarraytest类。

9. 下面就是OLE调用的基本方法了。

首先在 CNewoletestApp类的InitInstance()里添加初始化OLE代码。

BOOL suc=AfxOleInit(); // 初始化OLE

if (suc==FALSE)

{

::AfxMessageBox("初始化OLE失败!");

}

其次,在 CNewoletestDlg里包含plot_idl.h头文件;并从d:\MATLAB6p5\work\Myarraytest\src\myarraytest_idl_i.c中拷贝类的GUID并复制到PlotView.h文件类定义的上面。

#include "myarraytest_idl.h"

const CLSID CLSID_Myarraytest = {0x9C4328EF,0xEA57,0x4D84,{0x9C,0x97,0xDE,0x4B,0xAE,0x02,0x21,0x5F}};

class CNewoletestDlg : public CDialog

{

// Construction

public:

IMyarraytest pResponse;

.....

}//double a[7][6];是我做其它测试程序用的。

然后,Onok()函数里添加获得COM指针的函数,代码如下:

plot.CreateDispatch(CLSID_plotclass,NULL); //创立接口

COleDispatchDriver(); //连接(此句可以不写)

pResponse.CreateDispatch(CLSID_Myarraytest,NULL); //创立接口

COleDispatchDriver(); //连接(此句可以不写)

VARIANT x;

VARIANT y;

VariantInit(&x); //初始化

VariantInit(&y);

x.vt=VT_ARRAY|VT_R8; //类型(数组,双精度型)

SAFEARRAYBOUND rgsabound[2];

rgsabound[0].cElements=2; //数组所含元素数

rgsabound[0].lLbound=0; //数组上界

rgsabound[1].cElements=2; //数组所含元素数

rgsabound[1].lLbound=0; //数组上界

//创立数组

x.parray=SafeArrayCreate(VT_R8,2,rgsabound); //创立二维数组

double b[2][2];

b[0][0]=20;

b[0][1]=24;

b[1][0]=12;

b[1][1]=15;

//锁定数组

SafeArrayLock(x.parray);

//数组传递数据

x.parray-pvData=b;

//调用方法

pResponse.arraytest(0,&y,x);

//解锁

SafeArrayUnlock(x.parray);

/*

The most generic MATLAB M-function is function [Y1, Y2, ..., varargout] = foo(X1, X2, ..., varargin)

This function maps directly to the following IDL signature.

HRESULT foo([in] long nargout,

[in,out] VARIANT* Y1,

[in,out] VARIANT* Y2,

.

[in,out] VARIANT* varargout,

[in] VARIANT X1,

[in] VARIANT X2,

..

[in] VARIANT varargin);

This IDL function definition is generated by producing a function with the same name as the original M-function and

an argument list containing all inputs and outputs of the original plus one additional parameter, nargout. (nargout

is not produced if you compile an M-function containing no outputs.) When present,

the nargout parameter is an [in] parameter of type long.It is always the first argument in the list.

This parameter allows correct passage of the MATLAB nargout parameter to the compiled M-code.

Following the nargout parameter, the outputs are listed in the order they appear

on the left side of the MATLAB function, and are tagged as [in,out], meaning that they are passed in both directions. The

function inputs are listed next, appearing in the same order as they do on the right side of the original function. All

inputs are tagged as [in] parameters. When present, the optional varargin/varargout parameters are always listed as the

last input parameters and the last output parameters. All parameters other than nargout are passed as COM VARIANT types.

Data Conversion Rules lists the rules for conversion between MATLAB arrays and COM VARIANTs.

*/

// ::AfxMessageBox("调用结束!");

pResponse.DetachDispatch();

pResponse.ReleaseDispatch();

10. 测试。

本文并没有给出函数调用的返回参数y的后处理,这是本文的一个缺点,我会继续努力,在数据返回这一方面多做些工作。

欢迎和我交流:

李立新 沈阳航空工业学院

QQ:84203273

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有