XPCOM的JS回调(VS2010)

news/2024/7/19 15:08:28 标签: XPCOM, JS, callback, C++, xulrunner

1.XPCOM的很多东西都和COM的内容很像。当然也就在类型上有很多麻烦的地方,在此也不再啰嗦,读者自己研究尝试。

这里只是做个简单的示例,用于XPCOM回调JS内容。


准备:

1.下载python2.7.3(高的版本貌似有点问题,木有深入研究过),并设置环境变量,网上很多,不再说。(加入ClassPath中即可)

2.在cmd下输入python+回车,出现下图,表示成功


3.下载xulrunner-sdk.zip。

4.建立模板工程。下载setup.js,进入setup.js目录,在cmd下,setup.js回车即可安装。setup.js代码如下。(注意暂时此setup.js只支持VS2010)

setup.js的代码如下:

main();

function main() {
    var debug = false;

    // Create shell object
    var shell = WScript.CreateObject("WScript.Shell");
    var fso = WScript.CreateObject("Scripting.FileSystemObject");
    
    // 当前目录
    var strCurrentDir = "";
    if (WScript.ScriptFullName.lastIndexOf("\\") != -1) {
        strCurrentDir = WScript.ScriptFullName.substring(0, WScript.ScriptFullName.lastIndexOf("\\")+1);
    }
    var strSourceFolder = fso.BuildPath(strCurrentDir, "XPCOMWizard");
    if (debug) {
        WScript.Echo("Source: " + strSourceFolder);
    }
    if (!fso.FolderExists(strSourceFolder)) {
        WScript.Echo("ERROR: Cannot find Wizard folder (should be: " + strSourceFolder + ")");
        return ;
    }
    
    // vcprojects目录
    var strProductDir = null;
    try {
        var strVC10Key = "HKLM\\Software\\Microsoft\\VisualStudio\\10.0\\Setup\\VC\\ProductDir";
        strProductDir = shell.RegRead(strVC10Key);
    }
    catch(e) {
        try
        {
            var strVC10Key_x64 ="HKLM\\Software\\Wow6432Node\\Microsoft\\VisualStudio\\10.0\\Setup\\VC\\ProductDir";
            strProductDir = shell.RegRead(strVC10Key_x64); 
        }
        catch(e) 
        {
            WScript.Echo("ERROR: Cannot find where Visual Studio 10.0 is installed.");
            return; 
        }
    }
    var strDestFolder = fso.BuildPath(strProductDir, "vcprojects");
    if (debug) {
        WScript.Echo("Destination: " + strDestFolder);
    }
    if (!fso.FolderExists(strDestFolder)) {
        WScript.Echo("ERROR: Cannot find destination folder (should be: " + strDestFolder + ")");
        return;
    }

    // 拷贝配置文件
    try {
        fso.CopyFile(fso.BuildPath(strSourceFolder, "XPCOMWizard.ico"), 
                     fso.BuildPath(strDestFolder, "XPCOMWizard.ico"));

        fso.CopyFile(fso.BuildPath(strSourceFolder, "XPCOMWizard.vsz"), 
                     fso.BuildPath(strDestFolder, "XPCOMWizard.vsz"));
    } catch(e) {
        var strError = "no info";
        if (e.description.length != 0)
            strError = e.description;
        WScript.Echo("ERROR: Cannot copy file (" + strError + ")");
        return;
    }
    
    // Create XPCOM folder
    try {
        var strDestXPCOMFolder = fso.BuildPath(strDestFolder, "XPCOM");
        if (!fso.FolderExists(strDestXPCOMFolder))
            fso.CreateFolder(strDestXPCOMFolder);
        if (debug) {
            WScript.Echo("XPCOM Folder: " + strDestXPCOMFolder);
        }
       fso.CopyFile(fso.BuildPath(strSourceFolder, "XPCOMWizard.vsdir"), 
                    fso.BuildPath(strDestXPCOMFolder, "XPCOMWizard.vsdir"));
    } catch(e) {
        var strError = "no info";
        if(e.description.length != 0)
            strError = e.description;
        WScript.Echo("ERROR: Cannot create XPCOM folder (" + strError + ")");
        return;
    }
    
    // Copy File
    try {
        var strDestFolder = fso.BuildPath(strProductDir, "VCWizards");
        if (!fso.FolderExists(strDestFolder))
            fso.CreateFolder(strDestFolder);
        strDestFolder = fso.BuildPath(strDestFolder, "AppWiz");
        if (!fso.FolderExists(strDestFolder))
            fso.CreateFolder(strDestFolder);
        strDestFolder = fso.BuildPath(strDestFolder, "XPCOMWizard");
        if (!fso.FolderExists(strDestFolder))
            fso.CreateFolder(strDestFolder);
        if (debug) {
            WScript.Echo("XPCOMWizard Folder: " + strDestFolder);
        }
        fso.CopyFolder(strSourceFolder, strDestFolder);
    } catch(e) {
        var strError = "no info";
        if (e.description.length != 0)
            strError = e.description;
        WScript.Echo("ERROR: Cannot copy XPCOMWizard folder (" + strError + ")");
        return;
    }

    WScript.Echo("XPCOMWizard Wizard successfully installed!");
}

这样就可以在VS中直接建立XPCOM的模板项目。


5.打开VS2010,在VS2010中,新建项目,如下图向导:

选好工程目录,然后点确定。

6.选择XULRUNNER的sdk包。如下图:


7.完成。然后自动生成的工程如下:


其中重点关注的是图中

标号1,是接口的声明和被外部调用的方法。变成后,单独编译此文件,可以自动生成相应的头文件和实现文件。

标号3,是外部调用的实现

标号2,是测试的js和js调用

标号4,是测试时要改的ID好,防止缓存,每次调JS测试时都要改ID号。否则测试不成功。


8.建立js回调的IDL,js回调,也就是XPCOM的计算结果写到JS中,让页面来调用,实现C++和JS的交互。

//这里的UUID可以通过VS【工具->创建GUID】自动生成
[scriptable, uuid(B62F393E-5122-4C4F-B189-5C69065155C9)]
interface IJSCallBack: nsISupports
{
	//这里的第一参数是标识,不能去掉,不然js回调不成功,一般默认的第一个标识的值默认为0
	//对于数据的结果,string类型其实不是XPCOM的类型,当遇到中文的时候往往会乱码,后面详细说
	//怎样转GBK都UTF8在页面上显示
	boolean call(in long bogus,in string aData);
};

[scriptable, uuid(671285FA-0055-438D-9F06-3169D99CF859)]
interface IXPCOMWizard55: nsISupports
{
    void Hello();
	//对于回调的JS直接用上面生成的接口作为输入类型就可以。
	//对于输出的参数,可以用out,但是在js中传入,一定要传入一个数组,也就是类型地址,才能正确的返回
	//当然要是觉得麻烦,也可以通过返回类型来做这个传出值。如下面:
	//long Sum(in long nFirst,in long nSecond,in IJSCallBack jsCallBack);
	void Sum(in long nFirst,in long nSecond,in IJSCallBack jsCallBack,out long nResult);
};

完成IDL后,直接编译就可以。会自动生成相应的接口。

相应实现的代码如下:

/**
 * @brief Say hello
 */
NS_IMETHODIMP XPCOMWizard55::Hello() 
{
#if defined(XP_WIN)
    ::MessageBoxW(NULL, L"Hello, XPCOM!", L"XPCOMWizard55", MB_OK|MB_ICONINFORMATION);
#endif
    return NS_OK;
    //return NS_ERROR_NOT_IMPLEMENTED;
}

/* void Sum (in long nFirst, in long nSecond, out long nResult); */
NS_IMETHODIMP XPCOMWizard55::Sum(int32_t nFirst, int32_t nSecond, IJSCallBack *jsCallBack, int32_t *nResult)
{
	//js输出值
	*nResult = nFirst + nSecond;

	char szResult[256] = {0};
	itoa(*nResult,szResult,10);

	if (jsCallBack)
	{
		bool bRet = false;
		//这里的第一个参数为0
		jsCallBack->Call(0,szResult,&bRet);
	}

	return NS_OK;
}

这样就实现了简单的js回调。

9.编写测试main.js(上图标号2),JS代码如下:

var test =
{
    call: function (index, data) {
        alert("call back result");
        alert(data);
    }

}

function doXpCOM() {
    try {
        //建立XPCOM的实例"@gw.com.cn/xpcomwizard55;1"是唯一的类值和XPCOM中一致。
        var aXPCOMWizard55 = Components.classes["@gw.com.cn/xpcomwizard55;1"]
                                  .createInstance(Components.interfaces.IXPCOMWizard55);
        aXPCOMWizard55.Hello();
        //输出值必须为数据,不然输出不正确
        var nResult = {};
        //调用XPCOM的方法,test直接写上面定义好的脚本函数
        aXPCOMWizard55.Sum(3, 5, test, nResult);
        alert("Return result:");
        alert(nResult.value);
    } catch (e) {
        alert(e);
    }
}

10.设置调试的应用程序。如下图:



11.编译,成功OK。

12.直接运行。结果如下图




OK成功!!




http://www.niftyadmin.cn/n/1285905.html

相关文章

刮刮卡demo-canvas实践

1、利用css将<li>与<canvas>层重叠&#xff1b; html<body><div id"wrap"><!-- 灰色涂层 --><canvas></canvas><!-- 刮卡结果 --><ul><li></li></ul></div> </body> 复制代码…

XP系统loadLibrary失败

现在的项目中开发的产品&#xff0c;在测试部门&#xff0c;一台机器上总是崩溃&#xff0c;而其他的机器都是好的。 最后打日志&#xff0c;log显示在loadLibray失败&#xff0c;排查了dll的依赖项&#xff0c;也没有问题。最后无奈&#xff0c;看到那台机器上用的是xp的sp1&a…

INT,INT32,_int64的范围

在做游戏的开发中&#xff0c;由于游戏运行的时间已经很长&#xff0c;数据量非常大&#xff0c;在内网测试&#xff0c;怎么测都没有问题&#xff0c;可是到外网就是时不时的挂了&#xff0c;后来打log才看出问题。是我的int类型范围设置小聊&#xff0c;数据较到&#xff0c;…

4月1日云栖精选夜读 | 代号“凤凰”,阿里新零售秘密武器,今年要打入100个城市 ...

【点击订阅云栖夜读周刊】 2019年&#xff0c;淘鲜达要在100个城市完成1000个门店的新零售改造。 热点热议 代号“凤凰”&#xff0c;阿里新零售秘密武器&#xff0c;今年要打入100个城市 作者&#xff1a;技术小能手 发表在&#xff1a;天下网商 阿里小二的日常工作要被TA们“…

vs2012连接sql2012,SQLDriverConnect问题

调试了半天&#xff0c;原来是忽略了字符编码的问题。 我的工程UNiCODE编码&#xff0c;但是我在传参数的时候传的const char*,我一直以为是我装sql2012的问题&#xff0c;折腾了半天的数据库&#xff0c;把该开的服务都开了&#xff0c;还是连接不上。 快绝望的时候&#xf…

【阿里云新品发布·周刊】第4期:快到飞起是怎样的体验?高达100万IOPS的高性能ESSD云盘!...

点击订阅新品发布周刊&#xff01; 新产品、新版本、新技术、新功能、价格调整&#xff0c;评论在下方&#xff0c;下期更新&#xff01;关注更多内容&#xff0c;了解更多 最新发布 RDS高性能ESSD云盘发布会2019年04月03日15时&#xff0c;阿里云推出&#xff1a;ESSD云盘是阿…

游戏服务器设计(转)

有段时间没有研究技术了&#xff0c;这次正好看到了新版的mangos&#xff0c;较之以前我看的版本有了比较大的完善&#xff0c;于是再次浏览了下他的代码&#xff0c;也借此机会整理下我在游戏服务器开发方面的一些心得&#xff0c;与大家探讨。另外由于为避免与公司引起一些不…

JDK 1.8 JVM的变化

前言&#xff1a; 1、什么是JVM JVM的全称是 Java Virtual Machine&#xff08;Java虚拟机&#xff09;&#xff0c;它通过模拟一个计算机来达到一个计算机所具有的功能。 Java和实体计算机一样也必须有一套合适的指令集&#xff0c;这个指令集能够被JVM解析执行&#xff0c;这…