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

C# 中的 COM 和组件创建

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.29/5 (28投票s)

2002年5月2日

7分钟阅读

viewsIcon

156123

downloadIcon

1

关于 C# 中 COM 组件创建的讨论。

引言

组件只不过是二进制形式的软件的可重用部分,可以插入到来自其他供应商的其他组件中。可重用的软件程序共享一个通用接口,允许轻松集成到应用程序中,也就是说,它是一个二进制标准,允许任何两个组件进行通信,该组件可以用任何语言编写。

组件的必要性

当今的应用程序开发耗时,维护困难且成本高昂,而且我们无法删除、升级或替换功能。解决这个问题的方法是可重用软件组件。每个函数都有一个独特的功能。

  • Microsoft Word - 文字处理软件。
  • Microsoft Excel - 电子表格 - 分析和数据处理。

在这种情况下,我们发现自己需要当前使用的应用程序中不包含的功能。

解决方案

解决此问题的方法是隔离许多应用程序所需的功能,并从中创建一个新应用程序,使其成为通用功能。每次客户端需要该功能时,都应该调用它并使用其功能,就好像它们是自己的功能一样。

在我们的项目中,我们从五个应用程序创建组件,以便用户可以轻松地在多种语言中使用它并轻松升级它。

COM 框架

要创建可以与其他任何应用程序交互的应用程序,需要有一种标准的方式来让这两个应用程序进行交互。因此,我们需要一个框架来定义使它们能够相互交互的规则,而不管谁创建了该应用程序。

COM 作为蓝图

如果所有应用程序都遵循相同的交互规则,那么由不同人员创建的应用程序就可以相互交互,我们可以利用任何应用程序来获取我们需要的功能。

Microsoft 定义了一个模型,该模型设定了使应用程序能够相互交互的标准。该模型被称为 COM。它定义了在实现后将使应用程序能够以统一的方式与其他应用程序交互的规则。调用应用程序和被调用应用程序都需要遵循 COM 指定的规则。

调用应用程序在硬盘上搜索会非常耗时。因此,COM 指出所有可以为其他应用程序提供服务的应用程序都必须在中央位置注册。但 COM 没有定义这个位置是什么,也没有定义要注册的信息。因此,COM 充当蓝图。所以 COM 只定义了理论,而不是如何实现它们。

Microsoft 的组件对象模型 (COM)

当我们注册 Windows 注册表中的 COM 或 DCOM 对象时,我们必须引用该对象的全局唯一标识符 (GUID),这是一个 128 位(16 字节)数字,可唯一标识该对象。每当客户端程序访问 COM 或 DCOM 对象时,客户端程序都会使用 GUID 在 Windows 注册表中引用该对象。

另一个强大的 COM 功能是语言独立性。COM 客户端和 COM 对象在运行时具有相同的布局和行为,无论我们使用哪种语言来生成组件。COM 独立于任何特定语言,这让我们能够使用其他程序员用不同语言(如 Visual Basic、C++ 或 Java)创建的许多不同组件来构建系统。用于创建组件的语言在 COM 中根本无关紧要。

  • 首先,它有助于在设计阶段早期将大型系统分解为可管理的子系统。
  • 其次,它有助于使用我们用任何支持 COM 的工具创建的组件来实现每个子系统。
  • 第三,它允许负责每个子系统的各个团队拥有完全的控制权。

其中最值得注意的两种技术是 OLE(对象链接与嵌入)和 ActiveX。它们都使用 COM 来促进对象之间的所有交互。OLE 使用 COM 在应用程序之间进行通信,允许用户将一个应用程序数据的某个部分链接或嵌入到另一个应用程序中并显示出来。

组件的接口

Microsoft 的接口定义语言 (IDL)

COM 和 DCOM 背后的基本概念是接口。接口是客户端和对象之间关于如何相互通信的约定。当我们在 Visual Basic 以外的语言中定义接口时,我们必须使用 Microsoft 的接口定义语言 (IDL),我们必须在 Microsoft Interface Definition Language Compiler (MIDL) 中编译它。

全局唯一标识符 (GUID)

我们在 COM 对象中定义的每个接口都将包含一个通用唯一标识符 (UUID),操作系统会像构造全局唯一标识符一样构造它。当客户端程序访问 COM 对象公开的接口时,程序实际上会引用接口的 UUID。接口是客户端和对象之间关于如何通信的约定。接口成为客户端和对象之间的通信通道。在我们程序的代码中,接口是相关过程和函数的集合。

接口的功能

当我们创建围绕 COM 构建的对象以及客户端与 COM 对象通信时,客户端和对象都必须仅通过接口进行通信。

两个对象之间的接口是实际的程序代码。逻辑接口是程序代码本身的模型。接口在客户端和对象之间扮演调解者的角色,并且是一个规定对象必须做什么工作的契约,但它不规定对象应该如何完成工作。此外,接口是一种通信协议,它定义了一组方法,包括名称、参数和返回类型。COM 对象必须至少实现一个接口,尽管对象可以自由实现它需要的任意数量的接口。对象会创建一个函数指针数组,称为 V 表(“V”代表 Virtual),并将 V 表指针传递给客户端。客户端将 V 表视为接口,并使用从客户端接收到的 V 表指针来定位特定的函数指针。当客户端找到函数指针时,客户端会直接调用该方法。

换句话说,当程序访问 COM 对象时,它们将始终访问 V 表并从 V 表接收 vptr。

当我们编译基于 COM 的项目时,编译器会将接口定义语言文件馈送给 Microsoft Interface Definition Language (MIDL) 编译器,生成一个名为类型库的二进制描述文件。

与 C++ 和 Java 不同,Visual Basic 不需要使用接口定义语言或 MIDL 编译器。Visual Basic 集成开发环境 (IDE) 直接从我们的 Visual Basic 源代码创建类型库,并构建类型库信息。

如果我们想查看特定 COM 组件的接口定义语言,我们可以使用 OLE View 实用程序将类型库“逆向工程”为接口定义语言文本。类型库允许开发工具(如 Visual Basic 编译器和 Visual J++ 编译器)在编译时构建表绑定。

C# 中的组件创建

互操作性

  1. C# 包括对 COM 和基于 Windows 的应用程序的原生支持。
  2. 允许受限制地使用原生指针。
  3. 用户不再需要显式实现未知和其他 COM 接口,这些功能已内置。
  4. C# 允许用户使用指针作为不安全的代码块来操作旧代码。
  5. 来自 VB .NET 和其他托管代码语言的组件可以直接在 C# 中使用。

编译组件

组件的创建只是在普通应用程序中编写一个类程序,但在编译时,我们必须创建一个库而不是应用程序。创建了一个可以供客户端应用程序使用的单独库文件后。

编译过程应如下所示:

csc /r: REFRENCE DLL /t library /out DLLNAME.DLL Program name.cs

编译代码中的 "/t library" 告诉 C# 编译器创建库,并告诉它

不要查找 'static Main() 方法。在 "/r" 中,我们必须添加所需的命名空间 DLL。编译后,我们就有了所需的库,可以供客户端应用程序使用。要在客户端应用程序中使用组件,我们必须像这样编译

csc \r:components library DLL name program name.cs

eg: csc /r: arun.dll component.cs

代码更简单,只有两个文件(客户端和服务器)需要处理。对于足够大的应用程序,C 代码的量将与 C# 代码的量相当。

结论

据微软的市场宣传,.Net 框架极大地简化了组件开发。创建和管理 dll 文件占用了大量 Windows 开发人员的资源。

C# 的主要优势来自于文件数量的减少以及复杂链接器选项和头文件的缺失。

© . All rights reserved.