출처: http://blog.xiaoduo.info/?p=38

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. interface JSCallback : nsISupports {
  2.     boolean call(in PRUint32 aData);
  3. }

And another interface looks like:

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

2. Complete the sum function’s cpp code.

  1. NS_IMETHODIMP TestJSCallback::Sum(PRUint32 first, PRUint32 second, JSCallback *aCallback) {
  2.     PRBool ret = TRUE;
  3.     nsCOMPtr<JSCallback> js_callback = aCallback;
  4.     js_callback->Call(first+second, &ret);
  5. }

3. Interface call.

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

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

9 Responses to “XPCOM: Javascript function call”

  1. John SWITZERLAND Linux Mozilla Firefox 2.0.0.4 Says:

    thanks for the tip, that’s really smart. I’m now able to trig a js function from my c++ xpcom component. The only bug is that the parameter given to the callback are not correctly handled, ie they appears as ‘undefined’ in the js function. Any idea?

  2. Santa UNITED STATES Windows XP Internet Explorer 7.0 Says:

    Do you have all the code?

  3. kid.duo CHINA Mac OS X Mozilla Firefox 2.0.0.12 Says:

    You can check out the Firetray’s source code from google code.
    Or browse it online via http://code.google.com/p/firetray/source/browse

  4. Santa UNITED STATES Windows XP Internet Explorer 7.0 Says:

    The information all works upto the point of calling JS with parameters.
    The parameter is coming out “undefined”.

    The info in this thread is great with that caveat. How to make it work?

  5. Santa UNITED STATES Windows XP Internet Explorer 7.0 Says:

    I got the solution to my own post. I’ll post it asap.

  6. Santa UNITED STATES Windows XP Internet Explorer 7.0 Says:

    You have to call from javascript to XPCOM once the callback is called. That is the only way I can think so far.

  7. Tur SPAIN Windows XP Mozilla Firefox 2.0.0.12 Says:

    Hi, nice article, but I am not able to pass the argument to the JavaScript callback.
    I just get an alert window saying “undefined”. Does anybody knows how to solve this issue?
    Santa, can you explain further your workaround? Do you mean store the data in a variable in XPCom component and then in the call back recover that info from JavaScript?

  8. Tur SPAIN Windows XP Mozilla Firefox 2.0.0.12 Says:

    Hey I ‘ve discovered something!!
    I was wondering why JSCallback interface should define a method named “call” and not any other name.
    I found that in JavaScript, if you define a function you create an object with a call() method!, so i decided to test this. In the JavaScript example above i called “test.call()”. After some more test I’ve discovered that test.call(0,3) makes an alert(3)!!.
    The last step was to do the same in the XPCom, so modify the idl for the callback:
    boolean call(in PRUint32 bogus, in PRUint32 aData);
    And the C++ code
    aCallback->Call(0, first+second, &ret);
    And I got it.
    Hope this helps any one.

    One final request. I don’t know how to use nsCOMPtr. Help linking (aditional libs) would be very appreciated.

  9. Santa UNITED STATES Windows XP Internet Explorer 7.0 Says:

    Do this:
    http://www.mail-archive.com/dev-tech-xpcom@lists.mozilla.org/msg00531.html
    if you want parameters.

AND