65.9K
CodeProject 正在变化。 阅读更多。
Home

COM-.NET 互操作漫游

starIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIconemptyStarIcon

1.64/5 (10投票s)

2007年2月17日

7分钟阅读

viewsIcon

47911

这将帮助您理解,我们如何创建可以与 .NET 进行通信的对象,反之亦然。

在 .NET 中使用 COM 组件

引言

本文将帮助您理解 .NET 环境与 COM 组件(它们只是 Win32 动态链接库和 ActiveX 控件)之间的互操作性。

也就是说,.dll 和 .ocx 文件。

背景

设想一下,如果您有几个 COM 组件,包括 DLL 和 ActiveX 组件,现在是时候升级应用程序的功能和 UI 了,同时还需要通过 Web 来提供应用程序。所以,我决定用 .NET 编写部分应用程序,这样就可以消除 Web 部署以及 DLL 和 ActiveX 的注册问题。

在上述场景中,您可以选择完全重写一个纯 .NET Framework 应用程序,或者在新的 Web 应用程序和桌面应用程序中利用现有的业务逻辑功能。是的,我谈论的是 COM-.NET 互操作,这是我们能够与 COM 组件通信,反之亦然的方式。

让我们开始深入探讨,找出 COM 互操作到底是什么,以及实现它的不同方法。

DLL 和 OCX 文件究竟是什么?

动态链接库 (DLL) 是一个代码文件,包含可以从其他可执行代码(应用程序或其他 DLL)调用的函数。程序员使用 DLL 来提供可重用的代码,并随产品一起分发。与可执行文件 (EXE) 不同,DLL 不能直接运行。DLL 必须从其他正在执行的代码调用。

DLL 是一个以 .DLL 扩展名命名的文件。

例如:> kernell32.dll, msvbvm60.dll, msvcrt32.dll

简单来说,DLL 是一个包含可供外部世界调用的函数的文件,外部世界可以利用这些函数调用。这里的外部世界就是指另一个 DLL 或应用程序。

另一方面,OCX 或简称 ActiveX 组件是组件(DLL 和 OCX 合称为 ActiveX 组件)。在下一节中,我们将了解 ActiveX 组件究竟是什么。

ActiveX 组件

ActiveX 控件实际上就是“OLE 对象”的另一种说法,或者更具体地说,“组件对象模型 (COM) 对象”。换句话说,一个控件至少是一个支持 IUnknown 接口并且是自注册的 COM 对象。通过 QueryInterface,容器可以管理控件的生命周期,并根据可用的接口动态发现控件功能的完整范围。这允许控件实现尽可能少的功能,而不是支持大量实际上不做任何事情的接口。总之,仅仅需要 IUnknown 接口和自注册这一最低要求,就可以使任何控件都尽可能轻量级。除了 IUnknown 和自注册之外,对控件没有其他要求。但是,关于支持接口在控件为容器提供的功能方面意味着什么,也应该遵循一些约定。本节将描述控件实际支持接口意味着什么,以及控件在有机会支持方法、属性和事件时应提供的基线。

我认为,这足以说明我们如何以及在何处可以与 .NET 中的 COM 进行交互,反之亦然。

运行时可调用包装器 (Runtime Callable Wrappers)

如背景中所述,.NET 应用程序很可能需要与 COM 进行互操作,我们首先将找出如何实现这一点。 .NET 应用程序通过运行时可调用包装器 (Runtime Callable Wrappers) 或 RCW 来访问 COM。RCW 包装 COM 对象,充当 COM 和 .NET 运行时之间的桥梁,并且就像 RCW 是原生对象一样。

我们可以通过两种方式生成 RCW。第一种,使用 Visual Studio .NET。在 Microsoft Visual Studio .NET 中,右键单击项目中的“引用”部分(如果看不到项目下的“引用”部分,请单击“解决方案资源管理器”窗口中的“显示所有文件”图标,默认情况下,“引用”部分在 Visual Studio 2005 中是隐藏的)。选择“添加引用”,您将看到对话框(图 1),在此您可以浏览要作为引用添加到项目中的 COM 组件。选择所需文件并单击“添加”,Visual Studio .NET 将创建 RCW 并将其作为引用添加到项目中。

<formulas /></formulas />

Screenshot - AddrefercenRCW.gif

(图 1.)

如果您不使用 Microsoft Visual Studio .NET 环境,还有另一种创建 RCW 的方法。安装 .NET Framework SDK (VS.NET) 时,系统会安装一套工具。其中一个工具称为 TlbImp.exe(类型库导入程序实用工具),可用于创建 RCW 或运行时可调用包装器。让我们找出如何实际导入 COM 作为引用,或者如何创建 RCW。

(注意:要运行此示例,请确保您的系统变量已设置库路径。)

例如,如果您想从命令行将 COMDemo.dll COM 组件添加为引用,则在命令行中输入以下内容。

C:\> tlbimp comdemo.dll

它将在您指定的目录中创建 RCW,现在您可以通过导入或创建对象在项目中使用 RCW。

COM 可调用包装器 (COM Callable Wrappers)

另一方面,假设您有一个已经支持 COM 的客户端,现在您想让它使用 .NET 对象而不是。这是一种不太常见的情况,因为它假设在 .NET 世界中进行了新的 COM 开发。但我可以轻松地看到这种情况发生,如果您有一个现有的 COM 客户端使用 10 个 COM 对象,而您现在想添加一个仅以 .NET 对象形式存在的功能集。 .NET Framework 也通过 COM 可调用包装器 (CCW) 支持这种情况。

这里发生的是完全相反的事情。CCW 包装 .NET 对象,使其可用于 COM 交互,它就像一个 COM 组件一样,供 .NET 世界之外的其他 COM 对象或应用程序使用。现在有一些规则需要我们遵循才能使其正常工作。首先,需要公开给 COM 的 .NET 组件必须具有强签名名称,否则 CLR 将无法识别它。其次,它必须驻留在本地计算机的全局程序集缓存 (GAC) 中。如果您希望您的 CCW 对其他应用程序也可用,那么它必须驻留在 GAC 中;如果不是(这种情况较少),那么它必须存在于应用程序目录中(然后它将充当私有程序集,仅可用于该特定应用程序)。实际上,COM 组件不知道在创建对象时如何传递参数,需要公开的 .NET 组件必须有一个默认构造函数(一个不带参数列表的构造函数)。

为了让 COM 组件能够找到 .NET 对象,您还需要为该 .NET 组件进行注册表项。我们可以使用一个名为 RegAsm.exe 的工具来实现这一点,该工具在安装 .NET SDK 时可用。要注册,请在命令行中键入以下内容。

C:\> regasm < .NET 组件的名称 >

注册成功后,COM 组件就可以利用 .NET 对象。

在下一篇文章中,我们将更深入地探讨如何创建用于 COM 交互的 .NET 组件以及如何控制其公开。

这里有一些您可以利用的有用信息。

1) 使用 Win32 命令行注册 DLL、OCX。在“开始”->“运行”中键入以下内容,以注册任何 dll 或 ocx 文件。Regsvr32 "path"\xyz.dll 或 Regsvr32 /i path"\xyz.dll

2) 要从 Windows 注册表中注销已注册的路径,请键入 Regsvr32 /u path"\xyz.dll

[注意:此注册方法仅适用于 COM 组件]

© . All rights reserved.