首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网络技术 > 网络基础 >

用基准C编写COM(一)COM in plain C,Part1

2012-11-07 
用标准C编写COM(一)COM in plain C,Part1原文:http://www.codeproject.com/Articles/13601/COM-in-plain-C

用标准C编写COM(一)COM in plain C,Part1

        原文:http://www.codeproject.com/Articles/13601/COM-in-plain-C

        如何在不使用MFC、ATL、WTL或其他框架下使用标准C来创建和使用COM组件

        下载例程-17.6kb

内容:

    简介    COM 对象和虚表    GUID    QueryInterface(), AddRef(), and Release()    IClassFactory对象    打包到DLL中    C++/C包含文件    定义文件( DEF)    安装DLL,注册对象    C实例程序    C++实例程序    修改代码    接下来是什么?

简介: 

        有大量例子教大家如何使用和创建COM/OLE/ActiveX组件,但这些例子大都使用了微软基础类(MFC)、.NET、C#、WTL,至少会使用了ATL,因为这些框架会提供给你一些已经“封装” 好了的模板代码。不幸的是,这些框架对程序员隐藏了所有底层细节,所以你永远不会真正明白使用COM组件的本质。更好的掌握如何使用一个特定的框架是建立在你熟练掌握COM的基础上。

        如果你正尝试不使用MFC、WTL、.NET、ATL、C#、或者甚至一些C++代码,只使用标准的C来处理COM对象,则这方面的例子和资料非常匮乏。本文就是介绍在不使用其他框架,只使用标准C创建COM组件文章系列的第一部分。

        对于标准的Win32控件,例如Static、Edit、ListBox、ComboBox等,你可以获得一个控件的句柄(也就是一个HWND)并通过发消息(通过 SendMessage)给它来操纵它。同时当这个控件要通知你一些事情或给你一些数据时,它也通过消息的形式返回给你(也就是通过把它们放入你自己的消息队列中,你再通过GetMessage获取他们)。

        对于一个OLE/COM对象而言则完全不是这样。你不能来回发消息,取而代之的是,COM对象给你一些可以调用来操纵这个对象的一些函数指针。例如,一个IE浏览器对象会给你一 个函数指针,通过这个指针你可以调用来引发浏览器在你的一个窗口中去加载并显示Web页面。一个Office的对象会给你一个函数指针,你可以通过它加载一个文档。如果COM对象要通知你一些事情或发给你一些数据,那么你需要在你的程序中写特殊的函数,提供这些函数的指针(给COM对象)以便对象在需要的 时候调用它们。换句话说你需要在你的程序中创建你自己的COM对象。其中在C中真正麻烦是怎么定义你自己的COM对象。为了这样做,你需要知道一个COM对象的每个细节-这些原始的东西在预制的框架中对你而言则是隐藏的,在接下来的一系列文章中我将展示它。

        总之,你通过调用COM对象中的函数来操纵它,同时它在你的程序中也是通过函数调用来通知你一些事情或传给你一些数据或通过其他方式与你的程序交互。这个方法类似于DLL中的函 数调用,就像在你的C程序中DLL也要调用函数一样-有几分像“回调”。但是与DLL不同的是,你不能用LoadLibrary()和GetProcAddress()去获得这个COM对象的函数指针。我们马上就会揭示它,你需要使用一个与之不同的操作系统函数来获得一个对象指针,然后 用这个对象去获得指向它的函数的指针。

COM对象和虚表

        在学习怎样使用COM对象之前,我们首先需要了解一下COM对象是什么。认识它的最好的方式是创建我们自己的COM对象。但在我们这样做之前,让我们给出一个C结构数据类型。作为一个C程序员,你应该对它相当熟悉。这是一个例子的定义,一个简单的结构(叫“IExample”),它包含两个成员-一个DWORD(通过“count” 成员名来存取)和一个80个字符长度的数组(通过“buffer” 成员名来存取)。

 用基准C编写COM(一)COM in plain C,Part1

       当你一运行GUIDGEN时,它自动生成一个新的GUID给你,显示在Result框中。注意在你的Result框中看到的会与上面的有所不同。毕竟,每个 单一的GUID生成与其他的是不同的。所以你最好看到一些与我看到的不同的东东。继续单击“NewGUID”按钮会看到一些不同的数字出现在Result框中。单击一整天,看看是否会生成同一个序列数超过一次,不会。同时,也没人会生成一些与你生成的序列相同的数。

        你可以单击“Copy”按钮来把这个信息传输到剪切板上,然后把它粘贴到其它地方(像你的源代码中)。这是我这样做,粘贴完的东东:

IExample.dspIExample.dswIExample.ncbIExample.optIExample.plg

         在剩下的文件(IExample.c、IExample.h、IExample.def)中搜索IExample字符串并用你自己的对象名替换它(例如,IMyObject.c等)。在这个目录下以你的新对象名创建一个新的VisulaC++工程,工程的类型要选“Win32 Dynamic-Link Library”。创建一个空的工程,然后把上面的三个文件加到工程中。你一定要用GUIDGEN.EXE给你的对象和它的虚表生成你自己的GUID。不要用我生成的GUID。替换.H文件中的GUID宏(同时记住也要替换GUID宏的<<name>>部分)。删除.C和.H文件中的SetString和GetString函数,添加你自己的函数。修改.H文件你添加的函数定义的INTERFACE宏。修改MyRealIExample的数据成员为你需要的。修改安装程序源文件中的前三个字符串。在这个例子程序中,搜索并替换IExample为你的对象名。

接下来是什么?

        虽然一个C或者C++程序,或者一个用大部分编译语言编写的程序,可以使用我们的COM对象,我们必须添加一些东东来支持大多数解释性语言来使用我们的对象,例如VisualBasic、VBScript、Jscript、Python等。这会是这个系列第二部分的主题。


2楼deco1515昨天 20:03
hr = IExample_Vtbl.QueryInterface(thisobj,vTableGuid, ppv); nIExample_Vtbl有没有错
1楼wqliceman5天前 08:16
翻译得不错,这个学习com帮助大呀,顶一个,谢谢楼主

热点排行
Bad Request.