xpcom:js 回调

9 篇文章 0 订阅

https://blog.csdn.net/ec06cumt/article/details/17507763


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的代码如下:

  1. main();  
  2.   
  3. function main() {  
  4.     var debug = false;  
  5.   
  6.     // Create shell object  
  7.     var shell = WScript.CreateObject("WScript.Shell");  
  8.     var fso = WScript.CreateObject("Scripting.FileSystemObject");  
  9.       
  10.     // 当前目录  
  11.     var strCurrentDir = "";  
  12.     if (WScript.ScriptFullName.lastIndexOf("\\") != -1) {  
  13.         strCurrentDir = WScript.ScriptFullName.substring(0, WScript.ScriptFullName.lastIndexOf("\\")+1);  
  14.     }  
  15.     var strSourceFolder = fso.BuildPath(strCurrentDir, "XPCOMWizard");  
  16.     if (debug) {  
  17.         WScript.Echo("Source: " + strSourceFolder);  
  18.     }  
  19.     if (!fso.FolderExists(strSourceFolder)) {  
  20.         WScript.Echo("ERROR: Cannot find Wizard folder (should be: " + strSourceFolder + ")");  
  21.         return ;  
  22.     }  
  23.       
  24.     // vcprojects目录  
  25.     var strProductDir = null;  
  26.     try {  
  27.         var strVC10Key = "HKLM\\Software\\Microsoft\\VisualStudio\\10.0\\Setup\\VC\\ProductDir";  
  28.         strProductDir = shell.RegRead(strVC10Key);  
  29.     }  
  30.     catch(e) {  
  31.         try  
  32.         {  
  33.             var strVC10Key_x64 ="HKLM\\Software\\Wow6432Node\\Microsoft\\VisualStudio\\10.0\\Setup\\VC\\ProductDir";  
  34.             strProductDir = shell.RegRead(strVC10Key_x64);   
  35.         }  
  36.         catch(e)   
  37.         {  
  38.             WScript.Echo("ERROR: Cannot find where Visual Studio 10.0 is installed.");  
  39.             return;   
  40.         }  
  41.     }  
  42.     var strDestFolder = fso.BuildPath(strProductDir, "vcprojects");  
  43.     if (debug) {  
  44.         WScript.Echo("Destination: " + strDestFolder);  
  45.     }  
  46.     if (!fso.FolderExists(strDestFolder)) {  
  47.         WScript.Echo("ERROR: Cannot find destination folder (should be: " + strDestFolder + ")");  
  48.         return;  
  49.     }  
  50.   
  51.     // 拷贝配置文件  
  52.     try {  
  53.         fso.CopyFile(fso.BuildPath(strSourceFolder, "XPCOMWizard.ico"),   
  54.                      fso.BuildPath(strDestFolder, "XPCOMWizard.ico"));  
  55.   
  56.         fso.CopyFile(fso.BuildPath(strSourceFolder, "XPCOMWizard.vsz"),   
  57.                      fso.BuildPath(strDestFolder, "XPCOMWizard.vsz"));  
  58.     } catch(e) {  
  59.         var strError = "no info";  
  60.         if (e.description.length != 0)  
  61.             strError = e.description;  
  62.         WScript.Echo("ERROR: Cannot copy file (" + strError + ")");  
  63.         return;  
  64.     }  
  65.       
  66.     // Create XPCOM folder  
  67.     try {  
  68.         var strDestXPCOMFolder = fso.BuildPath(strDestFolder, "XPCOM");  
  69.         if (!fso.FolderExists(strDestXPCOMFolder))  
  70.             fso.CreateFolder(strDestXPCOMFolder);  
  71.         if (debug) {  
  72.             WScript.Echo("XPCOM Folder: " + strDestXPCOMFolder);  
  73.         }  
  74.        fso.CopyFile(fso.BuildPath(strSourceFolder, "XPCOMWizard.vsdir"),   
  75.                     fso.BuildPath(strDestXPCOMFolder, "XPCOMWizard.vsdir"));  
  76.     } catch(e) {  
  77.         var strError = "no info";  
  78.         if(e.description.length != 0)  
  79.             strError = e.description;  
  80.         WScript.Echo("ERROR: Cannot create XPCOM folder (" + strError + ")");  
  81.         return;  
  82.     }  
  83.       
  84.     // Copy File  
  85.     try {  
  86.         var strDestFolder = fso.BuildPath(strProductDir, "VCWizards");  
  87.         if (!fso.FolderExists(strDestFolder))  
  88.             fso.CreateFolder(strDestFolder);  
  89.         strDestFolder = fso.BuildPath(strDestFolder, "AppWiz");  
  90.         if (!fso.FolderExists(strDestFolder))  
  91.             fso.CreateFolder(strDestFolder);  
  92.         strDestFolder = fso.BuildPath(strDestFolder, "XPCOMWizard");  
  93.         if (!fso.FolderExists(strDestFolder))  
  94.             fso.CreateFolder(strDestFolder);  
  95.         if (debug) {  
  96.             WScript.Echo("XPCOMWizard Folder: " + strDestFolder);  
  97.         }  
  98.         fso.CopyFolder(strSourceFolder, strDestFolder);  
  99.     } catch(e) {  
  100.         var strError = "no info";  
  101.         if (e.description.length != 0)  
  102.             strError = e.description;  
  103.         WScript.Echo("ERROR: Cannot copy XPCOMWizard folder (" + strError + ")");  
  104.         return;  
  105.     }  
  106.   
  107.     WScript.Echo("XPCOMWizard Wizard successfully installed!");  
  108. }  

这样就可以在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的交互。

  1. //这里的UUID可以通过VS【工具->创建GUID】自动生成  
  2. [scriptable, uuid(B62F393E-5122-4C4F-B189-5C69065155C9)]  
  3. interface IJSCallBack: nsISupports  
  4. {  
  5.     //这里的第一参数是标识,不能去掉,不然js回调不成功,一般默认的第一个标识的值默认为0  
  6.     //对于数据的结果,string类型其实不是XPCOM的类型,当遇到中文的时候往往会乱码,后面详细说  
  7.     //怎样转GBK都UTF8在页面上显示  
  8.     boolean call(in long bogus,in string aData);  
  9. };  
  10.   
  11. [scriptable, uuid(671285FA-0055-438D-9F06-3169D99CF859)]  
  12. interface IXPCOMWizard55: nsISupports  
  13. {  
  14.     void Hello();  
  15.     //对于回调的JS直接用上面生成的接口作为输入类型就可以。  
  16.     //对于输出的参数,可以用out,但是在js中传入,一定要传入一个数组,也就是类型地址,才能正确的返回  
  17.     //当然要是觉得麻烦,也可以通过返回类型来做这个传出值。如下面:  
  18.     //long Sum(in long nFirst,in long nSecond,in IJSCallBack jsCallBack);  
  19.     void Sum(in long nFirst,in long nSecond,in IJSCallBack jsCallBack,out long nResult);  
  20. };  

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

相应实现的代码如下:

  1. /** 
  2.  * @brief Say hello 
  3.  */  
  4. NS_IMETHODIMP XPCOMWizard55::Hello()   
  5. {  
  6. #if defined(XP_WIN)  
  7.     ::MessageBoxW(NULL, L"Hello, XPCOM!", L"XPCOMWizard55", MB_OK|MB_ICONINFORMATION);  
  8. #endif  
  9.     return NS_OK;  
  10.     //return NS_ERROR_NOT_IMPLEMENTED;  
  11. }  
  12.   
  13. /* void Sum (in long nFirst, in long nSecond, out long nResult); */  
  14. NS_IMETHODIMP XPCOMWizard55::Sum(int32_t nFirst, int32_t nSecond, IJSCallBack *jsCallBack, int32_t *nResult)  
  15. {  
  16.     //js输出值  
  17.     *nResult = nFirst + nSecond;  
  18.   
  19.     char szResult[256] = {0};  
  20.     itoa(*nResult,szResult,10);  
  21.   
  22.     if (jsCallBack)  
  23.     {  
  24.         bool bRet = false;  
  25.         //这里的第一个参数为0  
  26.         jsCallBack->Call(0,szResult,&bRet);  
  27.     }  
  28.   
  29.     return NS_OK;  
  30. }  

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

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

  1. var test =  
  2. {  
  3.     call: function (index, data) {  
  4.         alert("call back result");  
  5.         alert(data);  
  6.     }  
  7.   
  8. }  
  9.   
  10. function doXpCOM() {  
  11.     try {  
  12.         //建立XPCOM的实例"@gw.com.cn/xpcomwizard55;1"是唯一的类值和XPCOM中一致。  
  13.         var aXPCOMWizard55 = Components.classes["@gw.com.cn/xpcomwizard55;1"]  
  14.                                   .createInstance(Components.interfaces.IXPCOMWizard55);  
  15.         aXPCOMWizard55.Hello();  
  16.         //输出值必须为数据,不然输出不正确  
  17.         var nResult = {};  
  18.         //调用XPCOM的方法,test直接写上面定义好的脚本函数  
  19.         aXPCOMWizard55.Sum(3, 5, test, nResult);  
  20.         alert("Return result:");  
  21.         alert(nResult.value);  
  22.     } catch (e) {  
  23.         alert(e);  
  24.     }  
  25. }  

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



11.编译,成功OK。

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




OK成功!!



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值