[Project_owners] XPCOM call local function

Anton Glazatov antonglv at gmail.com
Mon Feb 2 03:50:33 PST 2009


joe,
 >> In this case _obj. foo (); can be used in other functions in 
ext1Component too, in original case this._obj will be null if it is used 
in other functions than init()

It is because 'createInstance' method makes new instance of 
'ext1Component' object each time it is called.
There is yet another two ways to avoid 'null' value of '_obj' object field.
1) 'getService' method may be used istead of  'createInstance' method, 
so only one instance of 'ext1Component' object will be created for all 
windows; it is analogue of way you has proposed (global variable), and 
here may be cross-windows 'callbacks': for example, window1 calls 
'init', then window2 calls another component's method, but '_obj' points 
to window1.
2) extension's object can have field to store 'ext1Component' instance, 
for example:
var extobject =
{
    mc: null,

    init: function ()
    {
        this. mc = Components. classes...
        this. mc. init (this);
    },
    go: function ()
    {
        this. mc. bar ();
    }
};
In case 2) each window can have its own instance of 'ext1Component' object.

joe ertaba wrote:
> Thank you very much Anton, examples helps me a lot.
> In order for future reference for other developers I have one 
> modification in (/components/ext1component.js) for both ext1 & ext2
>
> instead of:
> function ext1Component ()
> {
>     this. wrappedJSObject = this;
> }
> ext1Component. prototype =
> {
>     QueryInterface: function (iid)
>     {
>         if (!iid. equals (Components. interfaces. ext1Component) &&
>             !iid. equals (Components. interfaces. nsISupports))
>         throw Components. results. NS_ERROR_NO_INTERFACE;
>         return this;
>     },
>    
>     _obj: null,
>    
>     init: function (obj)
>     {
>         this. _obj = obj;
>         // ...
>         this. _obj. foo ();
>     }
> };
>
> use this one:
>
> *var _obj;*
>
> function ext1Component ()
> {
>     this. wrappedJSObject = this;
> }
> ext1Component. prototype =
> {
>     QueryInterface: function (iid)
>     {
>         if (!iid. equals (Components. interfaces. ext1Component) &&
>             !iid. equals (Components. interfaces. nsISupports))
>         throw Components. results. NS_ERROR_NO_INTERFACE;
>         return this;
>     },
>    
>   
>     init: function (obj)
>     {
>        * _obj = obj;*
>         // ...
>         *_obj. foo ();*
>     }
> };
>
> In this case _obj. foo (); can be used in other functions in 
> ext1Component too, in original case this._obj will be null if it is 
> used in other functions than init()
>
> -Joe
>
>
> On Mon, Feb 2, 2009 at 12:02 AM, Anton Glazatov <antonglv at gmail.com 
> <mailto:antonglv at gmail.com>> wrote:
>
>     >> Is it possible to declare object variable into the idl file?
>     No, it isn't possible. Component method's argument should
>     implement any interface.
>
>
>     >> but I think I should reverse them, something like
>     Yes, you are right.
>
>
>     >> I don't exactly know why I need QueryIntrface here in my
>     extension js file beside in component
>     If you will use wrappedJSObject in your component constructor (see
>     here:
>     https://developer.mozilla.org/en/How_to_Build_an_XPCOM_Component_in_Javascript),
>     you need not to define extra interface for callback.
>
>
>     >> Would you please give me a sample extension file
>     You can see attached files. The ext1 doesn't use wrappedJSObject,
>     and ext2 use wrappedJSObject.
>
>     Btw, there is third way to call extension's function from xpcom
>     component - you may use global notifications (see
>     nsIObserverService / nsIObserver).
>
>     joe ertaba wrote:
>
>         Thanks Anton
>
>         Second method looks great, but I have few problems with it
>
>
>            or you may implement any interface in your extension's
>         object, it
>            may be somethink like
>
>            // xpcom .idl
>            ...
>            interface YourComponent: nsISupports
>            {
>            ...
>              void init (in YourComponentCallback obj);
>            ...
>            };
>
>            interface YourComponentCallback: nsISupports
>            {
>            ...
>              void foo ();
>            ...
>            };
>
>
>
>         Is it possible to declare object variable into the idl file?
>         something like
>
>         interface YourComponent: nsISupports {  void init (in object
>         obj); };
>
>         As I think it doesnt mean to declare object in idl! so I
>         should use your trick, but I think I should reverse them,
>         something like
>
>         // xpcom .idl
>         ...
>
>         interface YourComponentCallback: nsISupports
>         {
>         ...
>          void foo ();
>         ...
>         };
>
>         interface YourComponent: nsISupports
>         {
>         ...
>          void init (in YourComponentCallback obj);
>         ...
>         };
>          
>
>            // xpcom
>            ...
>            extobject: null,
>            ...
>            init: function (obj) { this. extobject = obj; },
>            ...
>            bar: function () { this. extobject. foo (); }, // call
>         extension's
>            function
>            ...
>
>            // extension
>            var yourextensionobject =
>            {
>            ...
>            init: function () {
>              var mycomponent = Components. classes ["@yourcomponent.cid"].
>            createInstance (Components. interfaces. YourComponent);
>              mycomponent. init (this);
>            },
>            ...
>            foo: function () { ... },
>            ...
>            QueryIntrface: function (iid)
>            {
>              if ((!iid. equals (Components. interfaces. nsISupprots) &&
>            (!iid. equals (Components. interfaces.
>         nsIYourComponentCallback))
>            Components. results. NS_ERROR_NO_INTERFACE;
>              return this;
>            }
>
>
>         I don't exactly know why I need QueryIntrface here in my
>         extension js file beside in component, if it helps to declare
>         object (YourComponentCallback) then is it enough or some other
>         things also needed (in xpcom we need lots of other thing like
>         Factories, Modules,... )
>
>         Maybe I am somehow confized! because I never see idl &
>         QueryIntrface for normal js (not compont)
>
>         Would you please give me a sample extension file or at least
>         some toturial which explain these concepts :)
>
>         Thanks in advance
>         Joe
>
>         ------------------------------------------------------------------------
>
>         _______________________________________________
>         Project_owners mailing list
>         Project_owners at mozdev.org <mailto:Project_owners at mozdev.org>
>         https://www.mozdev.org/mailman/listinfo/project_owners
>          
>
>
>
>     _______________________________________________
>     Project_owners mailing list
>     Project_owners at mozdev.org <mailto:Project_owners at mozdev.org>
>     https://www.mozdev.org/mailman/listinfo/project_owners
>
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> Project_owners mailing list
> Project_owners at mozdev.org
> https://www.mozdev.org/mailman/listinfo/project_owners
>   



More information about the Project_owners mailing list