Search code examples
c++firefoxfirefox-addonxpcom

My Firefox extension is not working. What's the structure of a Firefox extension (XPI file) that uses C++ XPCOM components?


I have tried a million different things and can't get this to work.

Inside the xpi file I have:

* content folder
     -browserOverlay.js
     -browserOverlay.xul

* locale folder
     *en-US folder
         -browserOverlay.dtd
         -browserOverlay.properties
* skin folder
         -browserOverlay.css

I have Firefox 14.0.1 and The part of my "Hello World" extension that does not use XPCOM is working. All it does, for now, is add a toolbar with a button that when clicked displays "Hello World" and then attempts to run a C++ XPCOM component which I built using the Gecko SDK and compiled using VS 2005.

The browserOverlay.js file contains the following code:

/**
 * XULSchoolChrome namespace.
 */
if ("undefined" == typeof(XULSchoolChrome)) {
  var XULSchoolChrome = {};
};

/**
 * Controls the browser overlay for the Hello World extension.
 */
XULSchoolChrome.BrowserOverlay = {
  /**
   * Says 'Hello' to the user.
   */
  sayHello : function(aEvent) {
    let stringBundle = document.getElementById("xulschoolhello-string-bundle");
    let message = stringBundle.getString("xulschoolhello.greeting.label");

    window.alert(message);


    try
    {
      // normally Firefox extensions implicitly have XPCOM privileges
      //but since this is a file we have to request it.

      netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
      const cid = "@example.com/XPCOMSample/MyComponent;1";
      obj = Components.classes[cid].createInstance();
      // bind the instance we just created to our interface
      obj = obj.QueryInterface(Components.interfaces.IMyComponent);
    } catch (err) {
      alert(err);
      return;
    }
    var res = obj.Add(3, 4);
    alert('Performing 3+4. Returned ' + res + '.');
  }
};

When I click on the button I see the first alert window. When I click OK I see a window with the following error message:

TypeError: Components.classes[cid] is undefined

What am I doing wrong? Where within the xpi file am I supposed to place the .dll file? the .idl file? the .xpt file?


Solution

  • I guess that you are following an outdated tutorial, most tutorials haven't been updated to XPCOM changes in Gecko 2.0. But to your questions:

    Where within the xpi file am I supposed to place the .dll file?

    Anywhere you like. The traditional placement is inside the components/ subdirectory.

    the .idl file?

    It shouldn't be part of your extension, only the .xpt file.

    the .xpt file?

    Again anywhere you like but typically in the same directory as the .dll file.

    It is important that you add the necessary declarations to your chrome.manifest file however, usually something like this:

    interfaces components/mycomponent.xpt
    binary-component components/mycomponent.dll ABI=WINNT_x86-msvc
    

    See also documentation on what needs to change in the component code (there is an example in the Firefox source tree if you prefer it). Note that you have to compile your component with the Gecko SDK version that is matching the Firefox version where you want to use the component. So for Firefox 14 you need to use Gecko SDK 14. Since there no longer is any binary compatibility, your component will then only work in Firefox 14 and not Firefox 13 or Firefox 15.