首页 > 编程 > .NET > 正文

COM和.NET的互操作

2024-07-10 13:02:01
字体:
来源:转载
供稿:网友


.net framework的产生已经有两年多的时间了,有不少公司开始采用.net开发应用软件。但是很多公司在多年的项目应用中,开发了很多com、dcom组件,现在采用.net开发组件,使这些组件成为了遗留代码。由于在开发com组件时投入了大量的人力、财力,如何在.net环境下重用这些com组件就显得更有意义,本文将介绍使这些com组件“起死回生”的方法。

.net支持运行时通过com、com+、本地winapi调用与未管制代码的双向互操作性,bcl为此提供了一套类和属性,包括受管制对象生存期的精确控制等。要实现互操作性,必须首先引入.net framework的 system.runtime.interopservices命名空间。c#的语法为:

using system.runtime.interopservices;

而vb.net的语法为:

import system.runtime.interopservices

.net访问api

.net允许c#访问未管制的dll的函数。如要调用windows user32.dll的messagebox函数:

int messagebox(hwnd hwnd,lpctstr lptext, lpctstr lpcaption,uint utype)

可以声明一个具有dllimport属性的static extern方法:

using system.runtime.interopservices;

[dllimport(“user32.dll”)]

static ertern int messagebox(int hwnd,string text,string caption,int type);

然后在代码里面直接调用就可以了。这里要注意在调用返回字符串的api中使用stringbuilder对象。

.net访问com组件

从.net调用com组件比较容易,只要使用tlbimp.exe产生com的装配形式的warpclass,然后在.net项目中调用即可。

注意com的类型信息通过type library文件描述,.net装配件是自描述的。tlbimp的作用是从com组件及其类型信息中产生自描述的装配件。由于vb是进行com组件开发最简单的语言,所以我们以一个简单的vb com组件来说明。

1.编写vb组件

vb组件原码(文件名coaccount.cls)如下:

private m_balance as integer

’组件的私有成员变量

public sub deposit(sum as integer)

’存钱的方法

m_balance = m_balance + sum

end sub

public property get balance() as integer

’属性balance访问成员变量m_balance

balance = m_balance

end property

将上述代码编译生成coaccount.dll。

2. 产生.net可访问的包装类(assembly),使用tlbimp.exe产生.net装配件。

tlbimp /out:netaccount.dll coaccount.dll

3.在.net代码中访问

.net代码只需引用coaccount.dll,就可以像访问.net的装配件一样访问com组件。

将.net组件转化为com组件

因为.net装配件开发效率较高,先在.net环境下开发装配件,然后转化为com组件,由vb、asp等调用,可以加快开发进度。下面我们用一个例子简单阐述一下整个过程。步骤如下:

1.定义接口

com是通过抛出接口让外部应用调用的,每个接口、组件都有一个guid,在.net中开发com组件也不例外。

[guid(“18e2bcaf-f4b5-4031-8f84-fcfb1dc04877”)] //接口guid

public interface iaccount

//定义接口iaccount

{ [dispid(1)]

//每个方法或属性都具有dispid属性,是为了让vbscript等脚本语言调用

void deposit(int num);

//方法,实现存钱的功能

[dispid(2)]

int balance

//属性,查看当前的账户余额,只读。请注意.net下属性的定义方法

{ get; }

}

2.实现接口的派生类

[guid(“9e5e5fb2-219d-4ee7-ab27-e4dbed8e123e”), //组件的guid

classinterface(classinterfacetype.none)]

//指明组件的调用方式,支持后期绑定

public class netaccount:iaccount

//实现接口派生类,注意派生类要实现接口的所有方法。

{ private int balance;

//组件的私有成员变量(在.net中称为域(field))

public netaccount()

//构造函数,初始化成员变量

{ balance=10; }

public void deposit(int num)

//实现存钱方法。

{ balance+=num; }

public int balance

//实现balance属性,通过它访问成员变量

{ get

{ return balance; }

}

}

3.将.net私有装配件转化成公有装配件

.net下对装配件的调用,实际上是拷贝到调用应用程序的本地目录,称为私有装配件。要转化为com组件,首先要转化为公有装配件,也就是放到gac里。

(1) 创建强名字

为了使com对象能够被外部对象调用,类库组合必须有一个强名字。创建强名字需要用到sn.exe,语法为:sn -k account.snk, 然后将强名字拷贝到debug目录下。打开assemblyinfo.cs,并修改下面一行的内容:

[assembly: assemblykeyfile(@“account.snk”)]

(2) 将装配件转入gac

编译项目文件产生netaccount.dll文件,使用gacutil.exe装入gac:

gacutil -i netaccount.dll

(3) 注册装配件

在注册表里面注册装配件,允许com组件的客户调用,也可以生成注册表文件,以备将来调用。

regasm netaccount.dll

执行上述语句,则装配件可以被脚本语言调用。

(4) 导出类型库

为了可以在vb里面使用组件,必须使用tlbexp.exe导出com类型库。

tlbexp /out:netaccount.tlb netaccount.dll

经过上面的工作,就将一个.net装配件转化为com组件。需要注意的是:在com中调用.net对象需要具备以下条件:

● 类必须是public性质;

● 特性、方法和事件必须是public性质的;

● 特性和方法必须在类接口中定义;

● 事件必须在事件接口中定义。

(计算机世界报 第43期 c17、c18)


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表