XPCOM支持的每种语言都必须有自己的组件加载器。
XPCOM组件至少有三层,从里到外是:1)核心XPCOM对象。2)工厂代码 3)模块代码<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
核心XPCOM对象是实现你所需要的功能的对象,其他层是用来支持它,将它插入到XPCOM系统中的。一个单独的库可能有很多个这样的核心对象。
在核心对象层上面的是工厂层,工厂对象提供了XPCOM对象的基本抽象。
模块层在最外面,模块接口提供了另一种抽象—为工厂提供了抽象—并允许有多个工厂对象。从组件库的外部只有唯一的入口点,NSGetModule().这个入口点可以扇出任意工厂,从这些工厂创建出任意XPCOM对象
#include
<
stdio.h
>
#define
MOZILLA_STRICT_API
#include
"
nsIModule.h
"
#include
"
nsIFactory.h
"
#include
"
nsIComponentManager.h
"
#include
"
nsIComponentRegistrar.h
"

static
const
nsIIDkIModuleIID
=
NS_IMODULE_IID;
static
const
nsIIDkIFactoryIID
=
NS_IFACTORY_IID;
static
const
nsIIDkISupportsIID
=
NS_ISUPPORTS_IID;
static
const
nsIIDkIComponentRegistrarIID
=
NS_ICOMPONENTREGISTRAR_IID;

#define
SAMPLE_CID/

{0x777f7150,0x4a2b,0x4301,/


{0xad,0x10,0x5e,0xab,0x25,0xb3,0x22,0xaa}}
static
const
nsCIDkSampleCID
=
SAMPLE_CID;

class
Sample:
public
nsISupports

{
private:
nsrefcntmRefCnt;

public:
Sample();
virtual~Sample();
NS_IMETHODQueryInterface(constnsIID&aIID,void**aResult);
NS_IMETHOD_(nsrefcnt)AddRef(void);
NS_IMETHOD_(nsrefcnt)Release(void);
}
;

Sample::Sample()

{
:mRefCnt(0);
}
Sample::
~
Sample()

{
}

NS_IMETHODIMPSample::QueryInterface(
const
nsIID
&
aIID,
void
**
aResult)

{

if(aResult==NULL)
{
returnNS_ERROR_NULL_POINTER;
}
*aResult=NULL;

if(aIID.Equals(kISupportsIID))
{
*aResult=(void*)this;
}

if(aResult!=NULL)
{
returnNS_ERROR_NO_INTERFACE;
}
AddRef();
returnNS_OK;
}
NS_IMETHODIMP_(nsrefcnt)Sample::AddRef()

{
return++mRefCnt;
}
NS_IMETHODIMP_(nsrefcnt)Sample::Release()

{

if(--mRefCnt==0)
{
deletethis;
return0;
}
returnmRefCnt;
}

//
factoryimplementationclassforcomponent
class
SampleFactory:
public
nsIFactory

{
private:
nsrefcntmRefCnt;
public:
SampleFactory();
virtual~SampleFactory();
NS_IMETHODQueryInterface(constnsIID&aIID,void**aResult);
NS_IMETHOD_(nsrefcnt)AddRef(void);
NS_IMETHOD_(nsrefcnt)Release(void);
NS_IMETHODCreateInstance(nsISupports*aOuter,constnsIID&iid,void**result);
NS_IMETHODLockFactory(PRBoollock);
}
;
SampleFactory::SampleFactory()

{
mRefCnt=0;
}
SampleFactory::
~
SampleFactory()

{
}
NS_IMETHODIMPSampleFactory::QueryInterface(
const
nsIID
&
aIID,
void
**
aResult)

{

if(aResult==NULL)
{
returnNS_ERROR_NULL_POINTER;
}
*aResult=NULL;

if(aIID.Equals(kISupportsIID))
{
*aResult=(void*)this;
}
else

if(aIID.Equals(kIFactoryIID))
{
*aResult=(void*)this;
}

if(aResult!=NULL)
{
returnNS_ERROR_NO_INTERFACE;
}
AddRef();
returnNS_OK;
}
NS_IMETHODIMP_(nsrefcnt)SampleFactory::AddRef()

{
return++mRefCnt;
}
NS_IMETHODIMP_(nsrefcnt)SampleFactory::Release()

{

if(--mRefCnt==0)
{
deletethis;
return0;
}
returnmRefCnt;
}
NS_IMETHODIMPSampleFactory::CreateInstance(nsISupports
*
aOuter,
const
nsIID
&
iid,
void
*
*
result)

{
if(!result)
returnNS_ERROR_INVALID_ARG;
Sample*sample=newSample();
if(!sample)
returnNS_ERROR_OUT_OF_MEMORY;
nsresultrv=sample->QueryInterface(iid,result);
if(NS_FAILED(rv))


{
*result=nsnull;
deletesample;
}
returnrv;
}
NS_IMETHODIMPSampleFactory::LockFactory(PRBool
lock
)

{
returnNS_ERROR_NOT_IMPLEMENTED;
}
//
Moduleimplementation
class
SampleModule:
public
nsIModule

{
public:
SampleModule();
virtual~SampleModule();
//nsISupportsmethods:
NS_IMETHODQueryInterface(constnsIID&uuid,void**result);
NS_IMETHOD_(nsrefcnt)AddRef(void);
NS_IMETHOD_(nsrefcnt)Release(void);
//nsIModulemethods:
NS_IMETHODGetClassObject(nsIComponentManager*aCompMgr,constnsCID&aClass,constnsIID&aIID,void**aResult);
NS_IMETHODRegisterSelf(nsIComponentManager*aCompMgr,nsIFile*aLocation,constchar*aLoaderStr,constchar*aType);
NS_IMETHODUnregisterSelf(nsIComponentManager*aCompMgr,nsIFile*aLocation,constchar*aLoaderStr);
NS_IMETHODCanUnload(nsIComponentManager*aCompMgr,PRBool*_retval);
private:
nsrefcntmRefCnt;
}
;
//
----------------------------------------------------------------------
SampleModule::SampleModule()

{
mRefCnt=0;
}
SampleModule::
~
SampleModule()

{
}
//
nsISupportsimplemention
NS_IMETHODIMP_(nsrefcnt)SampleModule::AddRef(
void
)

{
++mRefCnt;
returnmRefCnt;
}
NS_IMETHODIMP_(nsrefcnt)SampleModule::Release(
void
)

{
--mRefCnt;
if(mRefCnt==0)


{

mRefCnt=1;/**//*stabilize这里为什么要设置为1呢?*/
deletethis;
return0;
}
returnmRefCnt;
}
NS_IMETHODIMPSampleModule::QueryInterface(REFNSIIDaIID,
void
**
aInstancePtr)

{
if(!aInstancePtr)
returnNS_ERROR_NULL_POINTER;
nsISupports*foundInterface;
if(aIID.Equals(kIModuleIID))
foundInterface=(nsIModule*)this;
elseif(aIID.Equals(kISupportsIID))
foundInterface=(nsISupports*)this;
else
foundInterface=0;
if(foundInterface)


{
foundInterface->AddRef();
*aInstancePtr=foundInterface;
returnNS_OK;
}
*aInstancePtr=foundInterface;
returnNS_NOINTERFACE;
}
//
CreateafactoryobjectforcreatinginstancesofaClass.
NS_IMETHODIMPSampleModule::GetClassObject(nsIComponentManager
*
aCompMgr,
const
nsCID
&
aClass,
const
nsIID
&
aIID,
void
**
result)

{
if(!kSampleCID.Equals(aClass))
returnNS_ERROR_FACTORY_NOT_REGISTERED;
if(!result)
returnNS_ERROR_INVALID_ARG;
SampleFactory*factory=newSampleFactory();
if(!factory)
returnNS_ERROR_OUT_OF_MEMORY;
nsresultrv=factory->QueryInterface(aIID,result);
if(NS_FAILED(rv))


{
*result=nsnull;
deletefactory;
}
returnrv;
}
NS_IMETHODIMPSampleModule::RegisterSelf(nsIComponentManager
*
aCompMgr,nsIFile
*
aPath,
const
char
*
registryLocation,
const
char
*
componentType)

{
nsIComponentRegistrar*compReg=nsnull;
nsresultrv=aCompMgr->QueryInterface(kIComponentRegistrarIID,(void**)&compReg);
if(NS_FAILED(rv))
returnrv;
rv=compReg->RegisterFactoryLocation(kSampleCID,"SampleClass",nsnull,aPath,registryLocation,componentType);
compReg->Release();
returnrv;
}
NS_IMETHODIMPSampleModule::UnregisterSelf(nsIComponentManager
*
aCompMgr,nsIFile
*
aPath,
const
char
*
registryLocation)

{
nsIComponentRegistrar*compReg=nsnull;
nsresultrv=aCompMgr->QueryInterface(kIComponentRegistrarIID,(void**)&compReg);
if(NS_FAILED(rv))
returnrv;
rv=compReg->UnregisterFactoryLocation(kSampleCID,aPath);
compReg->Release();
returnrv;
}
NS_IMETHODIMPSampleModule::CanUnload(nsIComponentManager
*
aCompMgr,PRBool
*
okToUnload)

{
*okToUnload=PR_FALSE;//wedonotknowhowtounload.
returnNS_OK;
}
extern
"
C
"
NS_EXPORTnsresultNSGetModule(nsIComponentManager
*
servMgr,nsIFile
*
location,nsIModule
**
return_cobj)

{
nsresultrv=NS_OK;
//Createandinitializethemoduleinstance
SampleModule*m=newSampleModule();
if(!m)


{
returnNS_ERROR_OUT_OF_MEMORY;
}
//IncreaserefcntandstoreawaynsIModuleinterfacetominreturn_cobj
rv=m->QueryInterface(kIModuleIID,(void**)return_cobj);
if(NS_FAILED(rv))


{
deletem;
}
returnrv;
}