《XPCOM组件开发》笔记(三)

XPCOM支持的每种语言都必须有自己的组件加载器。

      XPCOM组件至少有三层,从里到外是:1)核心XPCOM对象。2)工厂代码 3)模块代码<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

      核心XPCOM对象是实现你所需要的功能的对象,其他层是用来支持它,将它插入到XPCOM系统中的。一个单独的库可能有很多个这样的核心对象。

      在核心对象层上面的是工厂层,工厂对象提供了XPCOM对象的基本抽象。

      模块层在最外面,模块接口提供了另一种抽象为工厂提供了抽象并允许有多个工厂对象。从组件库的外部只有唯一的入口点,NSGetModule().这个入口点可以扇出任意工厂,从这些工厂创建出任意XPCOM对象

None.gif #include  < stdio.h >
None.gif
#define  MOZILLA_STRICT_API
None.gif#include 
" nsIModule.h "
None.gif#include 
" nsIFactory.h "
None.gif#include 
" nsIComponentManager.h "
None.gif#include 
" nsIComponentRegistrar.h "
None.gif
None.gif
static   const  nsIID kIModuleIID  =  NS_IMODULE_IID;
None.gif
static   const  nsIID kIFactoryIID  =  NS_IFACTORY_IID;
None.gif
static   const  nsIID kISupportsIID  =  NS_ISUPPORTS_IID;
None.gif
static   const  nsIID kIComponentRegistrarIID  =  NS_ICOMPONENTREGISTRAR_IID;
None.gif
None.gif
#define  SAMPLE_CID \
ExpandedBlockStart.gifContractedBlock.gif
dot.gif 0x777f71500x4a2b0x4301, \
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif0xad0x100x5e0xab0x250xb30x220xaa}}

None.gif
static   const  nsCID kSampleCID  =  SAMPLE_CID;
None.gif
None.gif
class  Sample:  public  nsISupports 
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif
private:
InBlock.gif    nsrefcnt mRefCnt;
InBlock.gif
InBlock.gif
public:
InBlock.gif    Sample();
InBlock.gif    
virtual ~Sample();
InBlock.gif    NS_IMETHOD QueryInterface(
const nsIID &aIID, void **aResult);
InBlock.gif    NS_IMETHOD_(nsrefcnt) AddRef(
void);
InBlock.gif    NS_IMETHOD_(nsrefcnt) Release(
void);
ExpandedBlockEnd.gif}
;
None.gif
None.gifSample::Sample()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    :mRefCnt(
0);
ExpandedBlockEnd.gif}

None.gifSample::
~ Sample()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
ExpandedBlockEnd.gif}

None.gif
None.gifNS_IMETHODIMP Sample::QueryInterface(
const  nsIID  & aIID, void   ** aResult)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif    
if (aResult == NULL) dot.gif{
InBlock.gif        
return NS_ERROR_NULL_POINTER;
ExpandedSubBlockEnd.gif    }

InBlock.gif    
*aResult = NULL;
ExpandedSubBlockStart.gifContractedSubBlock.gif    
if (aIID.Equals(kISupportsIID)) dot.gif{
InBlock.gif    
*aResult = (void *this;
ExpandedSubBlockEnd.gif    }

ExpandedSubBlockStart.gifContractedSubBlock.gif    
if (aResult != NULL) dot.gif{
InBlock.gif    
return NS_ERROR_NO_INTERFACE;
ExpandedSubBlockEnd.gif    }

InBlock.gif    AddRef();
InBlock.gif    
return NS_OK;
ExpandedBlockEnd.gif}

None.gifNS_IMETHODIMP_(nsrefcnt) Sample::AddRef()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
return ++mRefCnt;
ExpandedBlockEnd.gif}

None.gifNS_IMETHODIMP_(nsrefcnt) Sample::Release()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif    
if (--mRefCnt == 0dot.gif{
InBlock.gif    delete 
this;
InBlock.gif    
return 0;
ExpandedSubBlockEnd.gif    }

InBlock.gif    
return mRefCnt;
ExpandedBlockEnd.gif}

None.gif
None.gif
//  factory implementation class for component
None.gif
class  SampleFactory:  public  nsIFactory
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif
private:
InBlock.gif    nsrefcnt mRefCnt;
InBlock.gif
public:
InBlock.gif    SampleFactory();
InBlock.gif    
virtual ~SampleFactory();
InBlock.gif    NS_IMETHOD QueryInterface(
const nsIID &aIID, void **aResult);
InBlock.gif    NS_IMETHOD_(nsrefcnt) AddRef(
void);
InBlock.gif    NS_IMETHOD_(nsrefcnt) Release(
void);
InBlock.gif    NS_IMETHOD CreateInstance(nsISupports 
*aOuter, const nsIID & iid, void * *result);
InBlock.gif    NS_IMETHOD LockFactory(PRBool 
lock);
ExpandedBlockEnd.gif}
;
None.gifSampleFactory::SampleFactory()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    mRefCnt 
= 0;
ExpandedBlockEnd.gif}

None.gifSampleFactory::
~ SampleFactory()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
ExpandedBlockEnd.gif}

None.gifNS_IMETHODIMP SampleFactory::QueryInterface(
const  nsIID  & aIID, void   ** aResult)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif    
if (aResult == NULL) dot.gif{
InBlock.gif    
return NS_ERROR_NULL_POINTER;
ExpandedSubBlockEnd.gif    }

InBlock.gif    
*aResult = NULL;
ExpandedSubBlockStart.gifContractedSubBlock.gif    
if (aIID.Equals(kISupportsIID)) dot.gif{
InBlock.gif    
*aResult = (void *this;
ExpandedSubBlockEnd.gif    }

InBlock.gif    
else
ExpandedSubBlockStart.gifContractedSubBlock.gif    
if (aIID.Equals(kIFactoryIID)) dot.gif{
InBlock.gif    
*aResult = (void *this;
ExpandedSubBlockEnd.gif    }

ExpandedSubBlockStart.gifContractedSubBlock.gif    
if (aResult != NULL) dot.gif{
InBlock.gif    
return NS_ERROR_NO_INTERFACE;
ExpandedSubBlockEnd.gif    }

InBlock.gif    AddRef();
InBlock.gif    
return NS_OK;
ExpandedBlockEnd.gif}

None.gifNS_IMETHODIMP_(nsrefcnt) SampleFactory::AddRef()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
return ++mRefCnt;
ExpandedBlockEnd.gif}

None.gifNS_IMETHODIMP_(nsrefcnt) SampleFactory::Release()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif    
if (--mRefCnt == 0dot.gif{
InBlock.gif    delete 
this;
InBlock.gif    
return 0;
ExpandedSubBlockEnd.gif    }

InBlock.gif    
return mRefCnt;
ExpandedBlockEnd.gif}

None.gifNS_IMETHODIMP SampleFactory::CreateInstance(nsISupports 
* aOuter,  const  nsIID  &  iid,  void   *   * result)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
if (!result)
InBlock.gif        
return NS_ERROR_INVALID_ARG;
InBlock.gif    Sample
* sample = new Sample();
InBlock.gif    
if (!sample)
InBlock.gif        
return NS_ERROR_OUT_OF_MEMORY;
InBlock.gif    nsresult rv 
= sample->QueryInterface(iid, result);
InBlock.gif    
if (NS_FAILED(rv)) 
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
*result = nsnull;
InBlock.gif        delete sample;
ExpandedSubBlockEnd.gif    }

InBlock.gif    
return rv;
ExpandedBlockEnd.gif}

None.gifNS_IMETHODIMP SampleFactory::LockFactory(PRBool 
lock )
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
return NS_ERROR_NOT_IMPLEMENTED;
ExpandedBlockEnd.gif}

None.gif
//  Module implementation
None.gif
class  SampleModule :  public  nsIModule
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif
public:
InBlock.gif    SampleModule();
InBlock.gif    
virtual ~SampleModule();
InBlock.gif    
// nsISupports methods:
InBlock.gif
    NS_IMETHOD QueryInterface(const nsIID & uuid, void * *result);
InBlock.gif    NS_IMETHOD_(nsrefcnt) AddRef(
void);
InBlock.gif    NS_IMETHOD_(nsrefcnt) Release(
void);
InBlock.gif    
// nsIModule methods:
InBlock.gif
    NS_IMETHOD GetClassObject(nsIComponentManager *aCompMgr, const nsCID & aClass, const nsIID & aIID,void * *aResult);
InBlock.gif    NS_IMETHOD RegisterSelf(nsIComponentManager 
*aCompMgr, nsIFile *aLocation, const char *aLoaderStr,const char *aType);
InBlock.gif    NS_IMETHOD UnregisterSelf(nsIComponentManager 
*aCompMgr, nsIFile *aLocation, const char *aLoaderStr);
InBlock.gif    NS_IMETHOD CanUnload(nsIComponentManager 
*aCompMgr, PRBool *_retval);
InBlock.gif
private:
InBlock.gif    nsrefcnt mRefCnt;
ExpandedBlockEnd.gif}
;
None.gif
// ----------------------------------------------------------------------
None.gif
SampleModule::SampleModule()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    mRefCnt 
= 0;
ExpandedBlockEnd.gif}

None.gifSampleModule::
~ SampleModule()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
ExpandedBlockEnd.gif}

None.gif
//  nsISupports implemention
None.gif
NS_IMETHODIMP_(nsrefcnt) SampleModule::AddRef( void )
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
++mRefCnt;
InBlock.gif    
return mRefCnt;
ExpandedBlockEnd.gif}

None.gifNS_IMETHODIMP_(nsrefcnt) SampleModule::Release(
void )
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
--mRefCnt;
InBlock.gif    
if (mRefCnt == 0
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif        mRefCnt 
= 1/**//* stabilize 这里为什么要设置为1呢?*/
InBlock.gif        delete 
this;
InBlock.gif        
return 0;
ExpandedSubBlockEnd.gif    }

InBlock.gif    
return mRefCnt;
ExpandedBlockEnd.gif}

None.gifNS_IMETHODIMP SampleModule::QueryInterface(REFNSIID aIID, 
void **  aInstancePtr)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
if ( !aInstancePtr )
InBlock.gif        
return NS_ERROR_NULL_POINTER;
InBlock.gif    nsISupports
* foundInterface;
InBlock.gif    
if ( aIID.Equals(kIModuleIID) )
InBlock.gif        foundInterface 
= (nsIModule*this;
InBlock.gif    
else if ( aIID.Equals(kISupportsIID) )
InBlock.gif        foundInterface 
= (nsISupports*this;
InBlock.gif    
else
InBlock.gif        foundInterface 
= 0;
InBlock.gif    
if (foundInterface) 
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        foundInterface
->AddRef();
InBlock.gif        
*aInstancePtr = foundInterface;
InBlock.gif        
return NS_OK;
ExpandedSubBlockEnd.gif    }

InBlock.gif    
*aInstancePtr = foundInterface;
InBlock.gif    
return NS_NOINTERFACE;
ExpandedBlockEnd.gif}

None.gif
//  Create a factory object for creating instances of aClass.
None.gif
NS_IMETHODIMP SampleModule::GetClassObject(nsIComponentManager  * aCompMgr,  const  nsCID &  aClass, const  nsIID &  aIID, void **  result)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
if (!kSampleCID.Equals(aClass))
InBlock.gif        
return NS_ERROR_FACTORY_NOT_REGISTERED;
InBlock.gif    
if (!result)
InBlock.gif        
return NS_ERROR_INVALID_ARG;
InBlock.gif    SampleFactory
* factory = new SampleFactory();
InBlock.gif    
if (!factory)
InBlock.gif        
return NS_ERROR_OUT_OF_MEMORY;
InBlock.gif    nsresult rv 
= factory->QueryInterface(aIID, result);
InBlock.gif    
if (NS_FAILED(rv)) 
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
*result = nsnull;
InBlock.gif        delete factory;
ExpandedSubBlockEnd.gif    }

InBlock.gif    
return rv;
ExpandedBlockEnd.gif}

None.gifNS_IMETHODIMP SampleModule::RegisterSelf(nsIComponentManager 
* aCompMgr,nsIFile *  aPath, const   char *  registryLocation, const   char *  componentType)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    nsIComponentRegistrar
* compReg = nsnull;
InBlock.gif    nsresult rv 
= aCompMgr->QueryInterface(kIComponentRegistrarIID, (void**)&compReg);
InBlock.gif    
if (NS_FAILED(rv))
InBlock.gif        
return rv;
InBlock.gif    rv 
= compReg->RegisterFactoryLocation(kSampleCID,"Sample Class",nsnull,aPath,registryLocation,componentType);
InBlock.gif    compReg
->Release();
InBlock.gif    
return rv;
ExpandedBlockEnd.gif}

None.gifNS_IMETHODIMP SampleModule::UnregisterSelf(nsIComponentManager
*  aCompMgr,nsIFile *  aPath, const   char *  registryLocation)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    nsIComponentRegistrar
* compReg = nsnull;
InBlock.gif    nsresult rv 
= aCompMgr->QueryInterface(kIComponentRegistrarIID, (void**)&compReg);
InBlock.gif    
if (NS_FAILED(rv))
InBlock.gif        
return rv;
InBlock.gif    rv 
= compReg->UnregisterFactoryLocation(kSampleCID, aPath);
InBlock.gif    compReg
->Release();
InBlock.gif    
return rv;
ExpandedBlockEnd.gif}

None.gifNS_IMETHODIMP SampleModule::CanUnload(nsIComponentManager 
* aCompMgr, PRBool  * okToUnload)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
*okToUnload = PR_FALSE; // we do not know how to unload.
InBlock.gif
    return NS_OK;
ExpandedBlockEnd.gif}

None.gif
extern   " C "  NS_EXPORT nsresult NSGetModule(nsIComponentManager  * servMgr,nsIFile *  location,nsIModule **  return_cobj)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    nsresult rv 
= NS_OK;
InBlock.gif    
// Create and initialize the module instance
InBlock.gif
    SampleModule *= new SampleModule();
InBlock.gif    
if (!m) 
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
return NS_ERROR_OUT_OF_MEMORY;
ExpandedSubBlockEnd.gif    }

InBlock.gif    
// Increase refcnt and store away nsIModule interface to m in return_cobj
InBlock.gif
    rv = m->QueryInterface(kIModuleIID, (void**)return_cobj);
InBlock.gif    
if (NS_FAILED(rv)) 
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        delete m;
ExpandedSubBlockEnd.gif    }

InBlock.gif    
return rv;
ExpandedBlockEnd.gif}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值