有什么简单的方法可以用COM接口包装基于c ++的对象模型

时间:2010-04-08 13:23:44

标签: c++ com atlcom

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

有哪些快速有效的方法可以做到这一点。任何建议,链接到实用的“如何”文档将非常感谢。

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

附录..... 更多背景。对我来说,这是大约10年后再次访问投诉人。我在2000年之前的3年里做过MFC和ATL COM。我理解COM是什么,用C ++实现它的原则,线程模型等。任何“如何快速”的文档都不会盲目地引导我。重要的原则,更多的是它将成为一种指导性的再学习体验。

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

评论后的进一步背景...........

保持尽可能简单,单线程公寓模型和inprocess dll。

2 个答案:

答案 0 :(得分:6)

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

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

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

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

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

  1. 您在没有任何实现的情况下编写仅接口程序集并注册它。
  2. 您开发了一个实现此COM接口的.NET类。
  3. 您可以在http://www.codeproject.com/KB/COM/COMinDotNet.aspxhttp://www.codeproject.com/KB/cs/CreateActiveXDotNet.aspxhttp://msdn.microsoft.com/en-us/library/ms973807.aspx中查看相同版本的更简单版本,但我建议您使用“在.NET中构建COM服务器”的方式{ {3}}

    评论后更新:抱歉,您正在寻找解决复杂问题的简便方法。这是不可能的。

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

    例如,如果某人继承了您的类并且您稍后更改了某些私有成员,则会对所有继承的类产生影响。完整代码使用了您的C ++对象必须重新编译,至少因为sizeof(object)已被更改。 COM中不存在此类问题,因为使用您的对象的所有人都不会继承您的对象类。一个人通过接口使用您的对象,在修改基类的某些私有成员后,不会更改签名和sizeof()。您可以在线阅读Don Box经典书籍“Essential COM”第一章中的一些非常好的例子:http://www.codeproject.com/KB/COM/BuildCOMServersInDotNet.aspx。我还建议您阅读一篇小文章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,以了解COM和C ++对象之间的更多差异。

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

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

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

    然后在C#或C ++中创建一个新项目,并声明继承之前定义的接口的类。在实现此接口期间,您可以使用整个现有的C ++对象。因此,您将能够快速丰富您的目标。请按照http://edndoc.esri.com/arcobjects/9.0/ArcGISDevHelp/DevelopmentEnvs/COM/IntroToCOM.htm中详细说明的方式进行操作。 通过这种方式,您不必学习C ++中经典COM实现需要了解的大量技术细节。而且你将研究一个现代的.NET,而不是研究旧的和事实上死的(或没有进一步发展的)COM。

    很抱歉答案很长。

答案 1 :(得分:2)

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

  

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