I have wrote a blog post about how to call JavaScript function from C++ XPCOM (XPCOM: Javascript function call), but just found another way to achieve this goal by observer mechanism.

C++ XPCOM code:

1
2
nsCOMPtr<nsIObserverService> observerService = do_GetService("@mozilla.org/observer-service;1");
observerService->NotifyObservers(NULL, "ping", ToNewUnicode(NS_ConvertASCIItoUTF16("www.google.com")));

JavaScript code:

?View Code JAVASCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
const Cc = Components.classes;
const Ci = Components.interfaces;
 
var aObserver = { 
    observe: function(subject, topic, data) {
        if (topic == "ping") {
            alert("Ping: " + data);
        }   
    }   
};
 
var observerService = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
 
observerService.addObserver(aObserver, "ping", false);

In multithreading XPCOM, sometime we should call JavaScript function by nsIProxyObjectManager (JavaScript and UI are on a single thread, see nsISupports proxies and nsProxiedService.h for detail)

Tags: ,

Sometimes we need to call javascript function form a c++ xpcom. The following is a method for this.

1. Define your javascript callback interface in a IDL file.

1
2
3
interface JSCallback : nsISupports {
    boolean call(in PRUint32 bogus, in PRUint32 aData);
}

And another interface looks like:

1
2
3
interface TestJSCallback : nsISupports {
    void sum(in PRUint32 first, in PRUint32 second, in JSCallBack aCallback);
}

2. Complete the sum function’s cpp code.

1
2
3
4
5
6
7
8
NS_IMETHODIMP TestJSCallback::Sum(PRUint32 first, PRUint32 second, JSCallback *aCallback) {
    PRBool ret = true;
    nsCOMPtr<JSCallback> js_callback = aCallback;
 
    js_callback->Call(0, first+second, &ret);
 
    return NS_OK;
}

3. Interface call.

?View Code JAVASCRIPT
1
2
3
4
5
6
var test = function(sum) {
    alert(sum);
};
 
var com = Components.classes["XXXXXX"].getService(Components.interfaces.TestJSCallback);
com.sum(1, 2, test);

It will pop up a dialog shows “3″ … Cheers…

Tags: ,

XPCOM array

Mozilla December 20th, 2006

记录下 XPCOM 的 array 的使用.
一个传入 string array 的例子:
1. IDL 的定义

1
boolean Run(in PRUint32 count, [array, size_is(count)] in string args);

2. CPP 的实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
NS_IMETHODIMP nsAntlerIPC::Run(PRUint32 count, const char **args, PRBool *_retval) {
    char **child_argv = NULL;
 
    child_argv = (char **)nsMemory::Alloc(sizeof(char *) * (count + 1));    
 
    if (!child_argv)
        return NS_ERROR_OUT_OF_MEMORY;
 
    PRUint32 i;
    for (i=0; i<count; i++) {
        child_argv[i] = NS_CONST_CAST(char*, args[i]); 
    }
    child_argv[count] = NULL;
 
    return NS_OK;
}

3. JS 的调用

?View Code JAVASCRIPT
1
2
var  argv = new Array("Just", "for", "test.");
obj.Run(argv.length, argv);

Tags: