XPCOM的JS回调(VS2010)

来源:互联网 发布:单片机电压测量电路 编辑:程序博客网 时间:2024/06/08 19:26

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;//这里的第一个参数为0jsCallBack->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成功!!



0 0
原创粉丝点击