Closed Bug 10033 Opened 22 years ago Closed 22 years ago

forward declared iface not being resolved even though it is resolved in one xpt file


(Core :: XPConnect, defect, P3)

Windows NT





(Reporter: jband_mozilla, Assigned: jband_mozilla)



(1 file)

nsIObserver is clearly being resolved in xpcom_ds.xpt yet at runtime the
InterfaceInfo system is telling xpconnect that the interface is not resolved.

I'm setup to debug this. I'll try to figure it out.

from xpcom newsgroup....
John Bandhauer wrote:
> "William A. Law" wrote:
> >
> > John Bandhauer wrote:
> > >
> > > xpconnect only reflects methods where all the types can be
> > > converted. You have declared nsILocale as 'native'. This is the
> > > same (as far as xpconnect is concerned) as declaring it as a
> > > void*. If you declare nsILocale as an interface in idl then this
> > > function will get reflected into JavaScript.
> >
> > This reminds me of a problem I ran into a while back.  I had tried to
> > "forward declare" an interface in a .idl file using "interface
> > nsISomething;" and then declared a method that used this interface
> > type.  The method ended up not being "not a function."  I had to change
> > the forward declaration to '#include "nsISomething.idl"'.
> >
> > Is that restriction necessary?  I thought the xpconnect function
> > properties would be looked up on the fly (as they're used from JS) and
> > that the forward-declared interface type info would be found in its own
> > .xpt file.
> >
> > Of course this isn't too big a deal.  It just forces a different
> > strategy for .idl vs. .h files (and seems to make forward declaration of
> > interfaces kind of pointless).
> Bill,
> Your posting puzzled me because I'm was sure this works as you
> originally expected. I just wrote a little test that does a
> forward declare of an interface, uses the interface as a method
> param, and does not include the .idl file. This works fine for
> me. Perhaps there was some other 'variable' in the problem you
> had. Maybe the non-included .idl file was not in the build
> project before it got included in another file?

I'm not sure what "not in the build project before it got included in
another file" means.  The interface in question was part of the system
for some time before I tried to use it.

>                                                  Of maybe you had
> a typo in the call from JS?

I distinctly remember making a single change to the .idl and it fixed
the problem. You can see the evidence in
The "interface nsIObserver;" is still in there, commented out.

If I comment out the #include (and uncomment the forward declaration),
then this stops working again. I get:

sampleComponent is [xpconnect wrapped nsISupports]
JavaScript error: uncaught exception: Component returned failure code:
2 [nsISupports.QueryInterface, {file:
resources/nsSampleAppShellComponent.html, line: 17}]

That's not the "is not a function" error I recall from before (and as
was mentioned at the beginning of this thread).  But it demonstrates
some kind of difference between forward-declared interfaces and
fully-defined ones.

> Anyway, the forward declare pattern certainly should work. It
> works for me. I'd be happy to fix it if you hit on a case where
> it does not work for you. Please, don't feel that you have to
> work around a problem that I'm quite sure really isn't there.

Maybe there's just more to it than meets my (more) un-trained eye.  Have
a look at the code referenced above (it might only build/run on Win32,
Mike could you review this for me. This fixes the problem. I don't think it
introduces any new problems.

The problem was that if the unresolved entry was found first then when we hit
the resolved entry we would not look for the record that had already been added
to the name table. So, The iid table would get the new record, but the name
table ends up with two records for the same name. When it later does a lookup by
name it finds the unresolved record.

I also had to fix two other things while I was here..

I changed "found in IIDTable" to "shouldAddToIIDTable" (and switched the logic)
because it was driving me nutty. I also made the 'zero' iid into a static so it
would not get init'd every time through. [it just occered to me to make it const
too: "static const nsID zero =...". This is not in the dif. But it compiles and
John -

Your diff looks great.  Thanks for handling this.

Closed: 22 years ago
Resolution: --- → FIXED
fix checked in.
jband, could you please verify this one ?
Marking verified.
You need to log in before you can comment on or make changes to this bug.