6

我有一个预先存在的 c++ 对象模型,它代表应用程序的业务层。我希望能够将对象模型暴露给用其他语言编写的应用程序,即 vbscript、VB、javascript 等。我相信这样做的最佳方法是用 COM 层包装业务对象。

有什么快速有效的方法可以做到这一点。任何建议,实用的“如何”文档的链接将不胜感激。

因为我正在为此开始赏金,所以这里有一些针对潜在赏金猎人的额外指南:- 1)我已经决定采用 ATL 方法 2)我现在专门寻找非常好的“如何快速”的链接有关包装预先存在的 c++ 对象模型以使其可被 javascript 之类的脚本语言使用的文档 3) 带有小型工作示例的东西向我展示了需要将哪些代码添加到哪些文件中,例如进入 cpp 、 idl 和 hpp/ 的内容h 等。它必须包含一个示例,我可以编译测试和更改以获得更好的理解。

附录.....进一步的上下文。对我来说,这是大约 10 年后再次访问 COM。在 2000 年之前的 3 年里,我做了 MFC 和 ATL COM。我了解 COM 是什么,在 C++ 中用于实现它的原理、线程模型等。任何“如何快速”的文档都不会让我盲目地沉迷重要的原则,更多的是指导性的重新学习体验。

如果我有更多时间,我会深入研究 Troelsen 的“COM 和 ATL 3.0 开发人员研讨会”,这是一本非常好的书,但它是一个非常缓慢的启动(重新)启动。

评论后的进一步上下文............

使其尽可能简单,单线程单元模型和进程内 dll。

4

2 回答 2

6

我在http://www.codeproject.com/KB/COM/index.aspx?#COM/DCOM/COM+%20-%20Beginners为初学者找到了很好的文章集。这是:

http://www.codeproject.com/KB/COM/hellocom.aspx , http://www.codeproject.com/KB/COM/comintro2.aspx , http://www.codeproject.com/KB/COM/ comintro.aspxhttp ://www.codeproject.com/KB/COM/com_server_without_mfc_atl.aspx,http : //www.codeproject.com/KB/COM/com_in_c1.aspx

但是,如果您开始对 COM 对象进行编程,那么了解 COM 的线程模型非常重要。这在这里解释得很好

http://www.codeproject.com/KB/COM/CCOMThread.aspx , http://www.codeproject.com/KB/COM/CCOMThread2.aspx

但我决定回答你,因为我想建议选择其他一些现代方式。COM 技术非常古老。Dot NET 具有内部的所有功能,并将永久开发。因此,我从Building COM Servers in .NET中找到了一种最有趣的方法。您用 C# 编写完整的 COM 将您的 COM 对象的开发分为两部分:

  1. 您编写没有任何实现的仅接口程序集并注册它。
  2. 您开发了一个实现此 COM 接口的 .NET 类。

可以在http://www.codeproject.com/KB/COM/COMinDotNet.aspx、http://www.codeproject.com/KB/cs/CreateActiveXDotNet.aspx、http_ //msdn.microsoft.com/en-us/library/ms973807.aspx ,但我建议您使用http://www.codeproject.com/KB/COM/BuildCOMServersInDotNet中描述的“在 .NET 中构建 COM 服务器”的方式。 .aspx _

评论后更新:对不起,但您正在寻找一种解决复杂问题的简单方法。是不可能的。

理解这一点非常重要,尽管有类似的相似性,但面向对象的 C++ 和 COM 之间存在许多主要差异。重要的是要理解,COM 不是一种面向对象的语言,而是一种二进制协议。软件组件(COM 对象)是可重用代码的二进制单元。它解决了基于面向对象方法设计的程序的模块单独编译存在的许多问题。

例如,如果有人继承了你的类,而你后来更改了一些私有成员,它会对所有继承的类产生影响。使用 C++ 对象的完整代码必须至少重新编译,因为sizeof(object)已更改。COM 中不存在这样的问题,因为所有使用您的对象的人都不会继承您的对象类。一个通过接口使用您的对象,在您修改基类的某些私有成员后,该签名sizeof()不会被更改。您可以在线阅读 Don Box 的经典著作“Essential COM”的第一章中的一些非常好的示例:http: //books.google.co.uk/books ?id=kfRWvKSePmac&dq=essential+com&printsec=frontcover&source=bn&hl= en&sa=X&oi=book_result&resnum=6&ct=result. 我建议您还阅读一篇小文章http://edndoc.esri.com/arcobjects/9.0/ArcGISDevHelp/DevelopmentEnvs/COM/IntroToCOM.htm以了解 COM 和 C++ 对象之间的更多区别。

如果您将 C++ 对象重写为 COM 对象,您必须选择线程模型,您必须了解如何编写线程安全程序,或者您必须使用单线程单元模型。您的所有对象都将存在(分配和运行)在一个单独的线程中。如果您选择进程外 COM 对象(将创建一个包含所有对象的 exe),则将创建一个新进程。如果有人调用您对象的方法,则将完成所有参数的编组。参数编组意味着在另一个线程中分配内存并将所有参数复制到线程。我之前描述的所有这些东西都不是 C++ 对象的术语。我写这个只是为了清楚 COM 和 C++ 对象模型真的不一样。

因此,要包装现有的 C++ 对象,您必须定义一些纯虚拟类——您在对象中实现的接口。此接口必须以IDL/MIDLMicrosoft 接口定义语言)编写。这是最重要的!然后,您必须使用现有的 C++ 类将这些接口实现为 COM coclass 。

我敢肯定,如果您在 .NET 中完成这些工作,则无需学习 COM 开发人员通常需要了解的大量实现细节。您只需在 C#/C++(纯虚拟​​类)中定义一个接口并编译它。您可以在 Visual Studio 中为强签名程序集生成私钥。只需进入“签名”部分的项目设置并选择“签署程序集”,然后选择“新建”强名称密钥文件。就是这样。通过这种方式,您可以完全定义一个 COM 接口。将为您生成接口的 MIDL 版本。

然后,您在 C# 或 C++ 中创建一个新项目并声明继承您之前定义的接口的类。在实现此接口期间,您可以使用整个现有的 C++ 对象。因此,您将能够快速丰富您的目标。只需按照http://www.codeproject.com/KB/COM/BuildCOMServersInDotNet.aspx中详细描述的方式。通过这种方式,您将不必学习大量在 C++ 中实现经典 COM 所需的技术细节。您将学习现代 .NET,而不是研究旧的事实上已死(或未进一步开发)的 COM。

对不起,答案很长。

于 2010-05-03T16:23:19.517 回答
2

http://www.lambdasoft.dk/Comet/index.htm

Comet 是 COM 和 C++ 之间的语言绑定。它允许您进行 COM 客户端和 COM 服务器编程,而不依赖于 ATL 或 MFC。换句话说,Comet 是 ATL 的替代品。

于 2010-04-08T13:28:27.703 回答