分享
 
 
 

连接 COM 与 .NET 的桥梁(三)——COM 服务器的 COM Interop 方式

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

连接 COM 与 .NET 的桥梁(三)

COM 服务器的 COM Interop 方式

作者:caeser2

源代码下载

连接 COM 与 .NET 的桥梁(一)——预备知识

连接 COM 与 .NET 的桥梁(二)——COM 服务器的 P-Invoke 方式

本节部分内容要求读者熟悉COM的消息调用原理,原理请参见杨老师

专栏文章。

前文内容:

COM 服务器 -- COM 客户端

...

COM 服务器 -- .net客户端

1、P/Invoke

2、COM Interop(本节内容)

上回介绍了COM服务器端未知或没有接口时的调用方法P/Invoke,这回我们来探讨一下已知接口的情况,COM Interop 方式。

一、普通的接口函数调用

这部分的示例代码叫做ComP6srcDNet中的ComP5工程,呵呵,有点眼熟吧,其实我的目的只是想介绍.net部分,所以COM和MFC部分引自杨老师的“COM 组件设计与应用(七)——编译、注册、调用” ,只有Use_Net的代码是我写的,我在这里多谢杨老师啦,没有您前面栽的树,咱也没法乘凉哈^_^

虽然.net本身就是COM凤凰涅磐后的产物,从很多.net结构的工作原理中都能看到 COM 的影子,但是从.net的COM调用中可以很明显的看出,.net在淡化(隐藏)接口的作用,这一点从下面的代码中可以看到。

对于COM服务器的调用,需要先做以下三个操作:

1用regsvr32.exe注册COM。

2用Tlbimp.exe导出类型库。被导出文件可以是dll文件,也可以是tlb文件;导出后生成的文件默认命名为原COM名称后加Lib。

3"添加引用",详见下

然后就可以写调用代码了。

/*Simple2是杨老师写的COM服务器,带有Add(int,int)和Cat(BSTR,BSTR)两个函数

Use1、2、3、4、5是杨老师写的8种COM调用方法....不是我不会数数哦,不信你自己去看代码

Use_Net是我写的.net调用

在"解决方案"面版中选择"引用"项,鼠标右键"添加引用",将Tlbimp.exe生成的类型库文件添加进程序集。结果如图

也可以用[DllImport(...)]方法引用COM

*/

//写个引用,方便使用

using namespace Simple2Lib;

FunClass *m_pCom;//FunClass有点像MFC中包装过的智能指针xxxPtr

//初始化

try

{

m_pCom=new FunClass;//.net框架自动连接到COM服务器,不用我们动手^_^

}

catch(...)

{

MessageBox::Show("COM没有注册吧?");

Close();

}

//计算 or 连接。呵呵,这么写还真够简单的,两句话搞定,.net的异常机制会帮我们判断用户是想做加法,还是想做字符串连接

try

{

textBox3-Text=m_pCom-Add(

Convert::ToInt32(textBox1-Text),Convert::ToInt32(textBox2-Text)).ToString();

}

catch(...)

{

textBox3-Text=m_pCom-Cat(textBox1-Text,textBox2-Text);

}

这就完啦,是不是很容易呢?熟悉COM调用的读者可以发现,其中许多COM初始化及查找接口的工作都被.net隐藏了,一些常用的参数Marshal转换封送操作也自动处理了,这使得我们用.net客户端调用COM服务器比COM客户端调用COM服务器还要容易。

二、回调接口的调用

如果不支持COM消息机制,就不能算支持COM服务。我们先看看回调接口的调用方法。

示例代码叫做CallBackInterface中的CallBackInterface工程,还是引自杨老师的文章:“COM组件设计与应用(十四)——事件和通知

。其中:

Simple12项目改名为CallBack,实现有1个回调接口的CallBack.DLL(Simple12.DLL);

Use1项目改名为Use_MFC,实现用MFC调用CallBack.DLL;

Use_Net是我用.net框架写的。

不要忘了调用COM服务器需要做的3个操作啊!

//首先实现接口,写法完全模仿Use_MFC

#pragma once

using namespace CallBackLib;

namespace Use_Net

{

public __gc class CSink : public ICallBack//继承自回调接口

{

public:

CSink(TextBox *p,Label *q): textBox3(p) {}

private:

TextBox *textBox3;//用来显示结果

void CallBackLib::ICallBack::Fire_Result(int nResult)//实现回调接口的虚函数

{

textBox3-Text=nResult.ToString();

}

};

}

//怎么只实现了一个虚函数?其他的呢?呵呵,又是.net,它已经帮我们做好啦

CSink *sink; //实例化回调接口

Event1Class *m_spCom; //Event1Class有点像MFC中接口的智能指针xxxPtr

int m_dwCookie;//保存标志。什么,你不知道这个是干什么的?去问杨老师!^_^

//初始化

m_dwCookie = 0;

sink=new CSink(textBox3,label1);

try {

m_spCom=new Event1Class;//.net自动连接到COM服务器

}

catch(...)

{

MessageBox::Show("杨老师说:注册了吗?COM初始化了吗?");

Close();

}

//连接

m_spCom-Advise(sink,&m_dwCookie);

//使用

try

{

m_spCom-Add(Convert::ToInt32(textBox1-Text),Convert::ToInt32(textBox2-Text));

}

catch(...)

{

MessageBox::Show("输入的格式不正确");

}

//断开

m_spCom-Unadvise(m_dwCookie);

m_dwCookie=0;

三、连接点的调用

这部分的示例代码是DispConnect中的DispConnect工程,还~~~是引自杨老师的文章:COM 组件设计与应用(十六)——连接点。其中:

Simple16项目名称变为SingleConnect,实现有1个连接点的SingleConnect.DLL;

MultConnect项目名称不变,实现有2个连接点的MultConnect.DLL;

Use项目变为Use_MFC,实现用MFC调用SingleConnect.DLL;

UseMult项目变为UseMult_MFC,实现用MFC调用MultConnect.DLL,并修复了老师在头文件上的一点错误:)

Use_Net是我用.net框架写的,实现用.net调用SingleConnect.DLL;

UseMult_Net是我用.net框架写的,实现用.net调用MultConnect.DLL。

不要忘了调用1个COM服务器需要做的3个操作啊!,这回要调用的是2个COM!

//Use_Net

DispConnectClass *sink;//声明包装类对象,有点像com客户端包装过的智能指针xxxPtr

//初始化

try

{

sink=new DispConnectClass;//.net帮我们自动连接到接口

}

catch(...)

{

MessageBox::Show("杨老师说:没有注册还是没有初始化?");

Close();

}

//连接

//用事件/委托模型替换了连接点模型。.net框架已经自动包装好委托了

sink-Result+=new _IDispConnectEvents_ResultEventHandler(this,My_ResultEvent);

//回调函数

private: System::Void My_ResultEvent(int e)//ATL的LONG类型被Marshal为int

{

textBox3-Text=e.ToString(); //textBox3用来显示结果

}

//使用

try

{

sink-Add(Convert::ToInt32(textBox1-Text),Convert::ToInt32(textBox2-Text));

}

catch(...)

{

MessageBox::Show("输入的数字格式不正确!");

}

//断开

//这步操作不需要了,.net在程序Close()时自动处理了

以此类推,多个连接点的UseMult_Net就很好理解了

DispConnectClass *sink;//声明包装类对象,有点像com客户端包装过的智能指针xxxPtr

//初始化

try

{

sink= new DispConnectClass;//.net自动帮我们连接到接口,Close()时自动断开

}

catch(...)

{

MessageBox::Show("杨老师说:没有注册还是没有初始化?");

Close();

}

//连接

//用事件、委托模型替换了连接点模型。.net框架已经自动包装好委托了

//奇怪,在"对象阅览器"中看不到"Timer"事件....Bug啊Bug,你怎么这么多捏?才写了几篇.net的文章,就发现这么多

sink-Timer+= new _IDispConnectEvents2_TimerEventHandler(this,My_TimeEvent);

sink-Result+=new _IDispConnectEvents_ResultEventHandler(this,My_ResultEvent);

//回调函数

private: System::Void My_TimeEvent(Object *e)//VARIANT被Marshal为Object*

{

label1-Text=e-ToString();//label1用来显示时间

}

private: System::Void My_ResultEvent(int e)//ATL的LONG类型被Marshal为int

{

textBox3-Text=e.ToString();//textBox3用来显示结果

}

//使用

//开始计时

sink-SetTimer(1000);

....

//停止计时

sink-KillTimer();

....

//Add(int,int)

try

{

sink-Add(Convert::ToInt32(textBox1-Text),Convert::ToInt32(textBox2-Text));

}

catch(...)

{

MessageBox::Show("输入的数字格式不正确!");

}

//断开

//这步操作不需要了,.net在程序Close()时自动处理了

四、ActiveX的调用

这个原理比较麻烦,但使用却很简单,MSDN以MediaPlayer控件(msdxm.ocx)举的例,大家感兴趣可以试试,我把它打包进tools中了。这里我换一个ActiveX,下载文件tools中的AxDemo.dll,是杨老师的文章......嗯~~还没发表出来啊,那我就代老师先把代码发表出来吧^_^,AxDemo.dll的代码大家自己去看示例文件ActiveXDemo中的ActiveXDemo工程,那可是我独家纰漏的、杨老师亲手写的、至今还未公开的绝密资料哟~~

AxDemo是杨老师用vc6写的ActiveX,注意不能用其它版本的vc重新编译;控件叫做ui Class;

Use_MFC和Use_Net是我写的调用。

MFC的调用步骤我不多说了,杨老师以后会告诉大家的,我只说说.net的调用步骤:

1.regsvr32.exe注册:

2.添加控件到工具箱中(.net窗体编辑器的右键菜单里的没有"插入ActiveX控件"项):

-

如果没有注册,则在列表中是找不到的。这时可以这样(编译器将自动注册):

3.将控件“画”在窗体中。编译器会自动调用Aximp.exe导出类型库:

4.编译、调试:

ActiveX相对于其它COM组件而言最舒服的地方是属性和事件可以直接在“属性”面版中调整,真正的可视化编程呐。

五、其它

遗憾的是,我使用的VS 2003(.net v1.1)不支持代码级别的C++ Interop方法,所以COM服务器方面我只能写到这里了,下一节我们开始讨论.net做服务器时的各种操作。

供下载的文件包中的tools文件夹提供了几个工具

名称

regsvr32.exe

TlbImp.exe

AxImp.exe

ildasm.exe

功能

注册COM控件

导出COM控件的类型库

ActiveX 控件的 COM 类型库中的类型定义转换为 Windows 窗体控件

用来反汇编.net程序,.exe和.dll文件均可

基本操作

注册:regsvr32 dll文件名

导出:TlbImp dll文件名

导出:aximp dll或ocx文件名

程序是窗口化的

反注册:regsvr32 /u dll文件名

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
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- 王朝網路 版權所有