Symbian Ecom 浅谈

Symbian Ecom框架的核心思想,其实就是 C++的虚函数和抽象类,也就是 C++的多态。

一个 Ecom的工程需要 3个子工程

    <1> 需要一个 Ecom的接口类 (interface工程 ), 也许还有解析器类及相应资源文件和相应代理和 mmp 文件 , 如果有解析器 , 则把解析器做成一个 dll

    <2> 插件类的实现( plugin工程) : 可以包括多个抽象接口类的实现 , 接口实现类继承自接口类;同解析器一样 , 也需要 相应资源文件和相应代理和 mmp 文件 , 这是一个 dll.

    <3> 调用接口类的 client(界面显示工程) ;

 

在整个 Ecom工程中的引导文件中即 bld.inf文件中,需要添加接口工程 , plugin工程和界面工程中的 mmp文件 .

eg:

PRJ_MMPFILES

../ interfaceDefinition /InterfaceDefinition.mmp
../plugin/group/EcomPlugin.mmp
../client/Group/EcomTest.mmp

 

<1>、先来说下接口类的实现 ( interface):

接口类主要有三个成员,

  1)、工厂函数;

  2)、纯虚函数(接口);

   (3)、 TUid的成员对象;

class EComInterface : public CBase
 {
public:

 //工厂的方法
 static EComInterface* NewL(const TDesC8& aOperationName);
 virtual ~EComInterface();
public:

 //接口的方法
 virtual TReal Calculate(TReal aA,TReal aB) = 0 ;
private:
 // 实现的标示
 TUid iDor_ID_Key;
 };

实现 工厂函数 的方法是在一个内联文件中,文件名一般是“.inl”;

inline EComInterface::~EComInterface()
 {

 //根据 iDor_ID_Key调用 delete方法把工厂函数获得的接口释放掉
 REComSession::DestroyedImplementation (iDor_ID_Key);
 }

// NewL 函数 , 创建默认的接口实现 ,   REComSession::CreateImplementationL传入 了指定的接口实现 UID KCalculateInterfaceUid

inline EComInterface* EComInterface::NewL (const TDesC8& aOperationName)
 {
 const TUid KCalculateInterfaceUid = {0xE0009DC2};

// 对于此 NewL, 可以不要 resolverParams 参数 .
 TEComResolverParams resolverParams;  // TEComResolverParams  作用 ?
 resolverParams.SetDataType (aOperationName);
 resolverParams.SetWildcardMatch (ETrue);

// 这个 iDor_ID_Key系统会自动分配 ,用于标识 接口类创建的实现
 TAny* interface = REComSession::CreateImplementationL(
   KCalculateInterfaceUid, _FOFF (EComInterface, iDor_ID_Key),
   resolverParams);
 
 return reinterpret_cast <EComInterface*> (interface);
 } //NewL

在系统启动时 , plug-in 工程会根据本工程的 dll_uid.rss 注册所有 接口实现 的信息 ECOM( 包括 plug-in 工程本身的 UID: dll_uid = 0xE8000079 , 接口 UID : interface_uid = 0x10009DC0 ,   接口实现 UID: implementation_uid = 0x10009DC3 ),   所以 , 如果 通过直接传递 UID( 当然你需要实现一个带 UID 参数的工厂方法 .) 到接口类的工厂方法中 , 并传递到 REComSession::CreateImplementationL , 就可以直接通过查找接口实现 plug-in 工程的所有接口实现信息表 , 就可以查找到相应接口实现 NewL 方法 , 并返回实例到 Client.

在接口的 NewL 方法中 , 你可以直接传递接口实现 UID( 当然你需要实现一个带 UID 参数的工厂方法 .), 这样的话就不需要解析器 .

你可以传递相应的非 UID 的参数 , 这样的话就需要解析器类 , 那么在这个工厂函数的实现中 , 需要指定 ECOM 接口的 UID 和解析器的 UID.

实现解析器类时 , 你需要实现解析器类的定义 (.h) 和实现 (.cpp) , 还要实现 UID.rss 代理文件及 mmp 文件 , plugin 中实现这些文件类似 .

ECOM 接口的解析器插件的实现 , 其实是实现一个 ECOM 框架定义的解析器接口 CResolver.

带解析器的情况需要把解析器的 UID和解析关键字作为参数传到 REComSession::CreateImplementationL ECom通过解析器 UID找到解析器,并且把 Inferface UID和解析关键字作为参数传入解析器。解析器会返回实现类的 UID ECom ECom再根据这个 UID构造 plug-in的实例并把接口指针返回给应用程序。

<2>、其次说说插件工程( plugin

这个工程中的类继承自接口类,需要实现接口类中的虚函数。

这里主要说说资源文件和代理的实现:

代理这个文件主要是实现一个函数和一个数组:

const TImplementationProxy ImplementationTable[] =
{
  IMPLEMENTATION_PROXY_ENTRY(0xE0009DC5, EComImplemetationPlus::NewL),
  IMPLEMENTATION_PROXY_ENTRY(0xE0009DC6, EComImplemetationMutiply::NewL)
};

EXPORT_C const TImplementationProxy *
 ImplementationGroupProxy(TInt& aTableCount)
 {
 aTableCount = sizeof(ImplementationTable) /
 sizeof(TImplementationProxy);
 return ImplementationTable;
 }

这里的两个 UID 0xE0009DC5 0xE0009DC6 必须和 接口实现工程的资源文件的 implementation_uid 相同,这样框架才能找到具体去实现哪一个插件的对象(也就是调用 EComImplemetationPlus::NewL 或者 EComImplemetationMutiply::NewL)。

这里资源文件的名字必须是 dll_uid + ".RSS"

RESOURCE      REGISTRY_INFO     theInfo
 {
 dll_uid = 0xE3CCB235;
 interfaces=
  {
   INTERFACE_INFO
    {
    interface_uid = 0xE0009DC2;
    implementations =
     {
     IMPLEMENTATION_INFO
      {
      implementation_uid = 0xE0009DC5;
      version_no = 1;
      display_name = "plus";
      default_data = "sum";
      opaque_data = "";
      },
      IMPLEMENTATION_INFO
      {
      implementation_uid = 0xE0009DC6;
      version_no = 1;
      display_name = "multiply";
      default_data = "multiply";
      opaque_data = "";
      }
     };
    }
  };
 }


这个子工程里面的 mmp文件:

TARGET   EComCalculatePlugin.dll
TARGETTYPE  PLUGIN
UID    0x10009D8D 0xE3CCB235
CAPABILITY      NONE

SOURCEPATH      ../src
SOURCE          proxy.cpp
SOURCE          EComImplemetationMutiply.cpp
SOURCE          EComImplemetationPlus.cpp

USERINCLUDE     . ../../interface ../inc
SYSTEMINCLUDE   /epoc32/include
SYSTEMINCLUDE   /epoc32/include/ecom

START RESOURCE  ../data/E3CCB235.RSS
    TARGET  EComCalculatePlugin.rsc
END

LIBRARY euser.lib ECom.lib

0x10009D8D 这个是 UID2 ,因为本工程是插件,所以 UID2必须是这个数 .

这里还有一个文件名位 main.cpp 他是 DLL插件的 main 函数:

#include <e32base.h>

GLDEF_C TInt E32DLL()
 {
 return (KErrNone);
 }

 

<3>  最后就是这个工程的节目显示( client)

 这工程里面就比较简单了,该怎么写就怎么写,和一般的 GUI程序时一样的。

调用工厂函数时: EComInterface* comInterface = EComInterface::NewL(aOperationName);

aOperationName 是参数,这个参数和 plugin工程 里面的资源文件中的 default_data 是一样的。

调用接口函数时: aResult = comInterface->Calculate(aA,aB);这个指针会自动调用相应对象的接口函数。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值