XPCOM示例

 

    首先,打开VS2010,新建一个Win32 Dynamic-Link Library空DLL项目,名称为XPCOMSample。

    该工程将有四个文件:CSample.h, ISample.idl, CSample.cpp, CSampleModule.cpp。其中,CSample.h和CSample.cpp是对ISample.idl的具体实现,CSampleModule.cpp定义了一些模块信息,如XPConnect使用的合约ID。

    首先新建名称为ISample.idl的文件:

#include "nsISupports.idl"

//uuid的内容(IID)可以使用GUID工具生成(guidgen.exe)
[scriptable, uuid(ED35BE65-DFA3-4674-B02D-161247F2CB0A)]
interface ISample : nsISupports
{
    attribute string Value;

    string Test(in string value);
};

    接着创建实现类CSample。编辑CSample.h内容如下:

#include "ISample.h"

#define NS_SAMPLE_CID { 0x45879e7c, 0x4d10, 0x460a, { 0xbe, 0x28, 0x2a, 0x6f, 0xdb, 0xc0, 0xe3, 0x92 } }
#define NS_SAMPLE_CONTRACTID "@sapmple.net/sample;1"

class CSample : public ISample
{
public:
    CSample();

    //声明继承自nsISupports的三个成员QueryInterface, AddRef 和 Release
    //有现成的宏可以使用,当然也可以自行书写
    NS_DECL_ISUPPORTS

    //声明继承自ISample的成员
    //有现成的宏可以使用,当然也可以自行书写
    //要注意的是,该宏由xpidl自动生成于ISample.h文件中;
    //另外,在ISample.h文件中,xpidl也会自动生成和本文件内容类似的实现类模板
    NS_DECL_ISAMPLE

private:
    ~CSample();

    char* mValue;
};


#include "CSample.h"
#include "nsMemory.h"
#include "nsEmbedString.h"
#include "nsIClassInfoImpl.h"

CSample::CSample() : mValue(nsnull)
{
    mValue = (char*)nsMemory::Clone("initial value", 14);
}

CSample::~CSample()
{
    if (mValue) nsMemory::Free(mValue);
}

NS_IMPL_CLASSINFO(CSample, NULL, 0, NS_SAMPLE_CID)
NS_IMPL_ISUPPORTS1_CI(CSample, ISample)

NS_IMETHODIMP CSample::GetValue(char** aValue)
{
    NS_PRECONDITION(aValue != nsnull, "null ptr");
    if (! aValue) return NS_ERROR_NULL_POINTER;

    if (mValue)
    {
        *aValue = (char*) nsMemory::Clone(mValue, strlen(mValue) + 1);
        if (! *aValue) return NS_ERROR_NULL_POINTER;
    }
    else *aValue = nsnull;

    return NS_OK;
}

NS_IMETHODIMP CSample::SetValue(const char* aValue)
{
    NS_PRECONDITION(aValue != nsnull, "null ptr");
    if (! aValue) return NS_ERROR_NULL_POINTER;

    if (mValue) nsMemory::Free(mValue);

    mValue = (char*) nsMemory::Clone(aValue, strlen(aValue) + 1);

    return NS_OK;
}

NS_IMETHODIMP CSample::Test(const char *value, char **_retval NS_OUTPARAM)
{
    NS_PRECONDITION(_retval != nsnull, "null ptr");
    if (! _retval) return NS_ERROR_NULL_POINTER;

    if (mValue)
    {
        *_retval = (char*) nsMemory::Clone(mValue, strlen(mValue) + 1);
        if (! *_retval) return NS_ERROR_NULL_POINTER;
    }
    else *_retval = nsnull;

    return NS_OK;
}

    最后,添加CSampleModule.cpp:

#include "mozilla/ModuleUtils.h"
#include "nsIClassInfoImpl.h"

#include "CSample.h"


NS_GENERIC_FACTORY_CONSTRUCTOR(CSample)
NS_DEFINE_NAMED_CID(NS_SAMPLE_CID);

static const mozilla::Module::CIDEntry kSampleCIDs[] = {
    { &kNS_SAMPLE_CID, false, NULL, CSampleConstructor },
    { NULL }
};

static const mozilla::Module::ContractIDEntry kSampleContracts[] = {
    { NS_SAMPLE_CONTRACTID, &kNS_SAMPLE_CID },
    { NULL }
};

static const mozilla::Module::CategoryEntry kSampleCategories[] = {
    { "my-category", "my-key", NS_SAMPLE_CONTRACTID },
    { NULL }
};

static const mozilla::Module kSampleModule = {
    mozilla::Module::kVersion,
    kSampleCIDs,
    kSampleContracts,
    kSampleCategories
};

NSMODULE_DEFN(CSampleModule) = &kSampleModule;

NS_IMPL_MOZILLA192_NSGETMODULE(&kSampleModule)

    代码部分到此就结束了,下面开始着手编译。首先为预处理器添加:XP_WIN和MOZ_NO_MOZALLOC:

    WChar_t视为内置类型设置为false:

    关闭预编译头:

    然后设置依赖项:xpcom.lib mozalloc.lib xpcomglue_s.lib nspr4.lib(替换原来默认的那些lib)

    设置添加各搜索目录(我的Gecho2.0的路径为D:\xulrunner-sdk\SDK):

    创建idl批处理文件(customBuild.bat):

D:/xulrunner-sdk/sdk/bin/xpidl.exe -I D:/xulrunner-sdk/sdk/idl -m header ISample.idl
D:/xulrunner-sdk/sdk/bin/xpidl.exe -I D:/xulrunner-sdk/sdk/idl -m typelib ISample.idl

    使用自定义构造步骤,以取代MIDL对idl的编译(在解决方案的ISample.idl文件上右键,选择属性):

应用后左侧的MIDL将作出变更:

    现在,就可以进行编译了。完成后,将获得ISample.h、ISample.xpt;在debug目录下还有:XPCOMSample.dll、XPCOMSample.lib

 

本人写的测试例子会报错:TypeError: Components.classes['@sapmple.net/sample;1'] is undefined

例子本身并没有错误,而是组件没有注册

 

如果有人知道放到FF Nightly11.0下,在js中进行测试的方法,请留言告知,谢谢

 

原来是权限的问题--
[15:23:26.061] netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");

[15:33:42.091] Use of enablePrivilege is deprecated.  Please use code that runs with the system principal (e.g. an extension) instead. @ file:///F:/tiewen/Mozilla/XPCOM/XPCOMSample/test.htm

二进制组件已不推荐使用,如果要用,需要封装到扩展中,真鸡巴恶心
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值