COM组件开发实践(六)---From C++ to COM :Part 3

在上一篇文章《COM组件开发实践(五)---From C++ to COM :Part 2 》中,我们进展到使用COM库加载C++对象了,这一篇中我们将真正将C++对象变成 COM对象,而在下一篇中我们将为它添加多接口支持。

C++对象变成COM对象

要将一个C++对象变成一个真正的COM对象,只需要如下操作:

1)实现接口的引用计数。因此每个COM对象都需要有两个函数用于管理引用计数:

ULONG AddRef();
  
ULONG Release();

这两个函数不返回HRESULT,因为它们不可能失败,除非对象已经不存在,而且它们也不需要返回值,因为它们只是简单地加减引用计数。

2)对象允许实现多个接口。假如对象要为不同的客户返回不同的接口,则需要客户告诉对象它需要哪个接口。实际上前面已经运用了一种方法:DllGetClassObject函数的IID参数。如果对象有多个接口,则类工厂对象的CreateDB函数(也就是真正创建对象的函数)应该增加一个参数:接口ID,即IID。

假如我们的DB对象有多个接口,一个接口用于建表,一个用于读写,一个用于获得数据库信息。我们可以让DB对象提供一个接口查询函数,

HRESULT QueryInterface(RIID riid,void** ppObj);

3)类工厂对象使用标准的IClassFactory接口。4)使用_stdcall调用约定。

5)实现DLL动态卸载。DLL的卸载由COM负责,COM查询DLL看是否还在使用,它会调用DLL的引出函数DllCanUnloadNow来判断是否可以卸载DLL.如果客户程序想让COM卸载所有未使用的库,它会调用CoFreeUnusedLibraries函数。

6)实现对象自动注册。只需要DLL实现两个引出函数DllRegisterServer和DllUnregisterServer

1,修改接口文件

1)将IDB由IUnknown派生,删除Release成员函数声明,为IDB所有成员函数添加_stdcall(因为COM对象在win32下采用标准调用约定)。2)删除类工厂IDBSrvFactory声明,因为我们现在要使用标准类工厂接口IClassFactory,同时也删除IID_IDBSrvFactory的声明。3)声明外部变量IID_IDB,

typedef long HRESULT;
#define DEF_EXPORT __declspec(dllexport)
// {30DF3430-0266-11cf-BAA6-00AA003E0EED}
extern const GUID CLSID_DBSAMPLE;
//{ 0x30df3430, 0x266, 0x11cf, { 0xba, 0xa6, 0x0, 0xaa, 0x0, 0x3e, 0xe, 0xed } };
// {30DF3432-0266-11cf-BAA6-00AA003E0EED}
extern const GUID IID_IDB;
//{ 0x30df3432, 0x266, 0x11cf, { 0xba, 0xa6, 0x0, 0xaa, 0x0, 0x3e, 0xe, 0xed } };
class IDB : public IUnknown
{
 // Interfaces
 public:
     // Interface for data access
    virtual HRESULT _stdcall Read(short nTable, short nRow, LPWSTR lpszData) =0;
    virtual HRESULT _stdcall Write(short nTable, short nRow, LPCWSTR lpszData) =0;
    // Interface for database management
    virtual HRESULT _stdcall Create(short &nTable, LPCWSTR lpszName) =0;
    virtual HRESULT _stdcall Delete(short nTable) =0;
    // Interfase para obtenber informacion sobre la base de datos
    virtual HRESULT _stdcall GetNumTables(short &nNumTables) =0;
    virtual HRESULT _stdcall GetTableName(short nTable, LPWSTR lpszName) =0;
    virtual HRESULT _stdcall GetNumRows(short nTable, short &nRows) =0;
    //virtual ULONG Release() =0;
};

时间: 2024-08-14 08:16:30

COM组件开发实践(六)---From C++ to COM :Part 3的相关文章

COM组件开发实践(八)---多线程ActiveX控件和自动调整ActiveX控件大小(下)

声明:本文代码基于CodeProject的文章<A Complete ActiveX Web Control Tutorial>修改而来,因此同样遵循Code Project Open License (CPOL). 在上一篇文章<COM组件开发实践(七)---多线程ActiveX控件和自动调整ActiveX控件大小(上)>中介绍了ActiveX控件中使用多线程的基本需求,并提出了一个简单的线程模型,但却出现了意想不到的问题,本文将尝试给出问题的一个可行的解法,并同时解决上文中提出

COM组件开发实践(五)---From C++ to COM :Part 2

一,使用抽象基类重用C++对象 在上一篇文章<COM组件开发实践(四)---From C++ to COM :Part 1>中,我们已经将要复用的C++对象封装到DLL中了,对象的声明和实现已经实现了剥离,但还有问题:对象的私有成员(如我们示例中CDB类的数组变量m_arrTables)还是被客户看得一清二楚,即使客户没办法去访问它们:若对象改变了它的数据成员的大小,则所有的客户程序必须重新编译. 而实际上,客户需要的仅仅是对象的成员函数的地址,因此使用抽象基类可以很好地满足以上需求,客户就不

ASP.NET2.0自定义控件组件开发 第六章 深入讲解控件的属性

原文:ASP.NET2.0自定义控件组件开发 第六章 深入讲解控件的属性                                         深入讲解控件的属性持久化(一) 系列文章链接: ASP.NET自定义控件组件开发 第一章 待续 ASP.NET自定义控件组件开发 第一章 第二篇 接着待续 ASP.NET自定义控件组件开发 第一章 第三篇 ASP.NET自定义控件组件开发 第二章 继承WebControl的自定义控件 ASP.NET自定义控件组件开发 第三章 为控件添加事件 前

COM组件开发实践(四)---From C++ to COM :Part 1

一,C++客户重用C++对象 假设已经有一个可以重用的类,我们就可以在自己的程序中去重用它,只需要将其定义和实现文件加入到我们自己的工程中,并且在使用它的文件中包含此类的定义文件就可以了,这也是我们最常用的C++标准重用方法.就拿我自己来说,在CodeProject上遇到比较好的控件代码,都是这样直接用到自己的项目中来的. 下面就给出我这个系列的第一个代码示例,在接下来的几篇文章中,将基于此代码不断进行改进,一步步从C++走向COM. 简单介绍下我们要重用的C++对象,它是一个简单的类似数据库的

COM组件开发实践(三)

前面两篇文章分别介绍了MFC ActiveX应用程序和使用ATL开发ActiveX的简单实例,但还有两个问题需要解决: 1)标记ActiveX控件为安全的控件 2)对控件进行数字签名.本文将结合这两点进行简单的介绍. Building a Safe ActiveX Control 如何不想办法将控件标记为安全的,就会在Web页面与控件进行交互时出现如下图的警告信息: 下面将分别介绍在MFC ActiveX和ATL中如何标记一个控件为安全的控件. 要标记一个MFC ActiveX控件为安全,可以仿

COM组件开发实践(一)

开发实践(一)-前端组件化开发实践"> Preface 因为项目需要,开始从事ActiveX方面的工作,看了一些资料,可惜都是些COM原理方面的,没有切合实际动手的东西,在CodeProject上读完David Marcionek的文章[1]后,收获良多,但也遇到一些恼人的小问题,因此在其基础上就一些易错点做些小注解.本文版权归David Marcionek所有. 简介 在本文中,我们将创建一个ActiveX控件,当加载控件时,它会显示一个动画进度条,以便向用户表明控件正在加载.此控件会包

COM组件开发实践(七)---多线程ActiveX控件和自动调整ActiveX控件大小(上)

声明:本文代码基于CodeProject的文章<A Complete ActiveX Web Control Tutorial>修改而来,因此同样遵循Code Project Open License (CPOL). 最近遇到两个需求:1)在ActiveX控件中使用工作线程来完成底层的硬件设备扫描任务,并在工作线程中根据操作结果回调外部web页面的JavaScript函数:2)能根据控件任务的不同自动调整控件大小.但在查阅了大量资料后,发现网上讨论ActiveX中多线程开发的文章基本没有,最后

COM组件开发实践(二)

假设需求如下:底层是一个数学运算库DLL,中间是ActiveX控件(它调用底层的数学运算库DLL来完成控制层),界面层在测试时可以是一个exe程序,最后发布到IE浏览器上测试. 数学运算库DLL的开发 新建一个Win32 DLL项目,加入一个头文件MyNum.h,在其中声明所有的数学函数(为简单起见,本文只考虑加法运算),代码如下: #ifndef MY_NUM_H #define MY_NUM_H int __stdcall AddNum(int,int); #endif 请注意这里的方法声明

ASP.NET自定义控件组件开发 第六章 深入讲解控件的属性

深入讲解控件的属性持久化(一) 自从写了控件开发的文章后,收到了不少朋友的来信,提出了不少的问题,感谢大家的关注.今天就 把大家说的一些问题来讲解下. 虽然我这个系列是控件开发,但是我的目的还是希望大家通过开发控件更加快速的对ASP.NET有更加深 入的了解,所以我们也很有必要把一些基础性的东西将清楚. 为了达到深入讲解属性的目的,我首先来讲讲页面周期和页面解析的一些问题: 1.页面的解析: 大家可能听说,页面在提交给服务器的时候,都是被解析成为了一个个的继承与Page的类,最直接的 证明就是: