.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;
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)
Java Asp PHP .Net XML C/C++ CGI VB Jsp J2ee J2se J2me EJB Servlet Tomcat Resin Struts Weblogic Eclipse ANT GUI JMS Web servise IDEA Webphere Hibernate Spring Jboss Applet Swing Socket Javamail Perl Ajax P2P 安全 模式 框架 测试 开源 游戏
Windows XP Windows 2000 Windows 2003 Windows Me Windows 9.x Linux UNIX 注册表 操作系统 服务器 应用服务器