XPCOM组件,数组作为传出和传入的参数,c++这种支持引用传参的语言与idl接口的声明是一致的,但
在javascript语言中,参数传递都是值传递,所以参数是不能直接作为返回值的。这样用javascript写xpcom
传入和传出参数时,就会有一些特殊的要求。
我们举一个简单的例子,在idl中,我们的有getArray,setArray接口,用它来说明如何使用javascript编
写含有数组参数的xpcom
- void getArray(out unsigned long count,[retval, array, size_is(count)] out string aArray);
- void setArray(in unsigned long count,[array,size_is(count)] in string aArray);
void getArray(out unsigned long count,[retval, array, size_is(count)] out string aArray); void setArray(in unsigned long count,[array,size_is(count)] in string aArray);
getArray有两个传出参数数组的大小count,数组本身。而javascript不支持引用传值,也不支持多个返回值,
这样就需要一些特殊的要求:
传出参数可以选择其一作为javascript语言对应的返回值。
传出参数需要使用对象把包装一下。
下面我们就以getArray为例说明这个问题:
在javascript对应的函数原型应该为:
- getArray: function(aCount){
- aCount.value = this.aArray.length;
- return this.aArray;
- }
getArray: function(aCount){ aCount.value = this.aArray.length; return this.aArray; }
这段代码,参数是一个表示数组大小的aCount,返回值为该数组,这就是接口声明中应该javascript的实现。
我们使用的时候可以这么写:
var aCount = {};
var array = xx.getArray(aCount);
我们看到传递的aCount是一个对象,这个和java想把一个值在参数中作为返回值(例如int),我们
写一个IntegerWrapper的思想是一样的:值传递直接把这个值使用参数作为返回值是不可能的,因为函数体所
见到的只是实参的副本。
- class IntergerWrapper{
- public int value;
- }
class IntergerWrapper{ public int value; }
因为数组的大小是能够直接通过array.length来得到的,所以aCount的返回值其实对我们没有,所以也为了简化一般写成:
var array = getArray({});
但是xpcom的返回的数组大小是固定的,js实现必须设置aCount.value = aArray.length;这样xpconnect才知道如何
将idl和javascript的实现结合起来。否则返回的数组是空的。
另外值得注意的是我们得到的数组是不能改变的,试图使用array.push操作是徒劳的,解决这个问题的办法,
通常是在接口中声明修改操作,然后实现该接口,例如增加add操作
idl:
void add(in string str);
对应的javascript实现:
- add: function(str){
- this.aArray.push(str);
- }
add: function(str){ this.aArray.push(str); }
传入数组相对就比较简单了:
js实现函数:
- void setArray: function(count,aArray){
- this.aArray = aArray;
- }
void setArray: function(count,aArray){ this.aArray = aArray; }
使用:
- aArray = ["ab","cd']
- xx.setArray(aArray.length,aArray);