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

一,使用抽象基类重用C++对象

在上一篇文章《COM组件开发实践(四)---From C++ to COM :Part 1》中,我们已经将要复用的C++对象封装到DLL中了,对象的声明和实现已经实现了剥离,但还有问题:对象的私有成员(如我们示例中CDB类的数组变量m_arrTables)还是被客户看得一清二楚,即使客户没办法去访问它们;若对象改变了它的数据成员的大小,则所有的客户程序必须重新编译。

而实际上,客户需要的仅仅是对象的成员函数的地址,因此使用抽象基类可以很好地满足以上需求,客户就不会包含对象的私有数据成员,就算对象改变了数据成员的大小,客户程序也不用重新编译。

1.修改接口文件

首先将接口都改成抽象基类,这是客户程序唯一所需要的代码。具体包括下面几步:1)将CDB和CDBSrvFactory的函数都改成纯虚函数。2)删除数据成员。3)删除所有成员函数的引出标志。4)将CDB改成IDB(表示DB的接口),CDBSrvFactory改成IDBSrvFactory(表示DB类工厂的接口)

typedef long HRESULT;
#define DEF_EXPORT __declspec(dllexport)
class IDB
{
  // Interfaces
public:
  // Interface for data access
  virtual HRESULT Read(short nTable, short nRow, LPWSTR lpszData) =0;
  virtual HRESULT Write(short nTable, short nRow, LPCWSTR lpszData) =0;
  // Interface for database management
  virtual HRESULT Create(short &nTable, LPCWSTR lpszName) =0;
  virtual HRESULT Delete(short nTable) =0;
  // Interfase para obtenber informacion sobre la base de datos
  virtual HRESULT GetNumTables(short &nNumTables) =0;
  virtual HRESULT GetTableName(short nTable, LPWSTR lpszName) =0;
  virtual HRESULT GetNumRows(short nTable, short &nRows) =0;
  virtual ULONG Release() =0;
};
class IDBSrvFactory
{
  // Interface
public:
  virtual HRESULT CreateDB(IDB** ppObject) =0;
  virtual ULONG  Release() =0;
};
  
HRESULT DEF_EXPORT DllGetClassFactoryObject(IDBSrvFactory ** ppObject);

2.修改对象程序

在DLL项目中,我们实现为这个抽象接口声明并实现具体的子类,让CDB从IDB派生,CDBSrvFactory从IDBSrvFactory派生,并且把类工厂CDBSrvFactory的CreateDB方法的参数由CDB**改成IDB**。

#include "..\interface\dbsrv.h"
typedef long HRESULT;
class CDB : public IDB
{
  // Interfaces
public:
  // Interface for data access
  HRESULT Read(short nTable, short nRow, LPWSTR lpszData);
  HRESULT Write(short nTable, short nRow, LPCWSTR lpszData);
  // Interface for database management
  HRESULT Create(short &nTable, LPCWSTR lpszName);
  HRESULT Delete(short nTable);
  // Interfase para obtenber informacion sobre la base de datos
  HRESULT GetNumTables(short &nNumTables);
  HRESULT GetTableName(short nTable, LPWSTR lpszName);
  HRESULT GetNumRows(short nTable, short &nRows);
  ULONG Release(); //CPPTOCOM: need to free an object in the DLL, since it was allocated here
  // Implementation
private:
  CPtrArray m_arrTables;   // Array of pointers to CStringArray (the "database")
  CStringArray m_arrNames; // Array of table names
public:
  ~CDB();
};
class CDBSrvFactory : public IDBSrvFactory
{
  // Interface
public:
  HRESULT CreateDB(IDB** ppObject);
  ULONG  Release();
};

这两个具体子类的实现代码在此就省略不表了,参考上篇文章。

时间: 2024-09-14 21:15:47

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

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,因为它们

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 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自定义控件组件开发 第五章 模板控件开发

大家好,我们今天来开发一个模板控件. 其实开发一个模板控件比开发一个组合控件更加简单,所以这章不难. 开发一个模板控件一般都继承CompositeControl,因为继承这个基类后,我们就省却了很多的麻烦. 所以本章我们开发的模板控件也继承于CompositeControl.大家应该还记得我们上章开发那个登录Login 控件吧,如下: 以上就是我们之前开发的登录控件,现在我们来改造它.我们的现在的这个登录控件的输入用户名和 密码的控件是TextBox,我们有时候可能想把TextBox 换成Dro

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

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