Date: | December 8, 2006 / year-entry #407 |
Tags: | code |
Orig Link: | https://blogs.msdn.microsoft.com/oldnewthing/20061208-00/?p=28783 |
Comments: | 26 |
Summary: | One of the more subtle ways people mess up IUnknown::QueryInterface is returning E_NOINTERFACE when the problem wasn't actually an unsupported interface. The E_NOINTERFACE return value has very specific meaning. Do not use it as your generic "gosh, something went wrong" error. (Use an appropriate error such as E_OUTOFMEMORY or E_ACCESSDENIED.) Recall that the rules for... |
One of the more subtle ways people mess up Recall that the rules for These rules exist for a reason. In the case where COM needs to create a proxy for your object (for example, to marshal the object into a different apartment), the COM infrastructure does a lot of interface caching (and negative caching) for performance reasons. For example, if a request for an interface fails, COM remembers this so that future requests for that interface are failed immediately rather than being marshalled to the original object only to have the request fail anyway. Requests for unsupported interfaces are very common in COM, and optimizing that case yields significant performance improvements. If you start returning Save yourself and the COM folks several hours of frustration. Don't return |
Comments (26)
Comments are closed. |
There’s a way to clean the cache? In a developement environment it
would be possible that at some early stage of a project QueryInterface
would retutn E_NOINTERFACE because the requested interface is not yet
supported.
Lorenzo: the cache is per-object (not class), so it is necessarily not persistent. i.e. If you restart you application you’ll get a clean cache.
Is this behavior documented?
Mr. Chen,
On a recent post, you determined that you should become a professional psychic since your predictions seem to have a reasonably high favorable probability. Perhaps we should turn your powers to something very useful such as answering the following:
How many of those in my comments section who claim to be professional developers have actually seen at least one day of formal training?
How many of those in my comments section really do read the API documentation and perform adequate research as opposed to "programming from the hip?"
Why do so many of those in my comments section not believe in things such as backward compatibility and good interface design?
And last, but not least: Why is it that no matter how hard I work my life out to ensure back compat, security, and stability in every line of code I write for Windows, Microsoft is seen as inherently evil while linux can break almost every driver written for it when upgrading from kernal version 2.4 to 2.6 and it is seen as a godsend?
James
James – you forgot one:
6. Why not delete random off-topic rants?
> Use an appropriate error such as E_OUTOFMEMORY or E_ACCESSDENIED
we shouldn’t return E_NOTIMPL??
Or here’s a question: Why must every thread this month involve sycophantic praise of Microsoft and knee-jerk retaliatory bashing of Linux and /.? Seriously, man, pretty much every post you make follows the same formula.
More on topic, it seems from reading the linked COM article that rule 1 for supporting extensions, whether you’re writing a shell or just a Winamp plugin, seems to be that version 1.0 must enforce every conceivable restriction, including the ones that don’t seem to make any sense. If this proves to be sluggish in practice, just do it for any plugin timestamped within the last two months.
Bob,
I’m going to assume you were speaking to me so apologies up front if I’m wrong. As to your question, here is my answer:
Because for the past several YEARS every other article on slashdot involved abhorrent hatred of Microsoft and knee-jerk retaliatory bashing of Windows.
I find it strange how it’s cool to go in one direction and not cool to go in the other.
James
What, even the articles about solar panels? Perhaps some people are smarting from Linux being regarded as a toy even when it does what people need better than certain other OSes. It’s also irritating that people assume the only reason that MS stuff is so regularly rooted is popularity and nothing to do with design or priorities.
Did something change just recently that would make such bugs more visible? This seems *psychically* close to something I am experiencing.
An application that I depend on registers a COM object in ROT. I retrieve a proxy to it and ask for a couple of interfaces. It gives me both under Windows XP, but only one under Vista. With E_NOINTERFACE on the other interface.
Random Linux User: Windows is trash
Me: Still 94.16% of people use Windows
Random Linux User: Linux is better for everything
Me: Seriously, who gives a damn?
Take a look at this:
http://marketshare.hitslink.com/report.aspx?qprid=2&qptimeframe=M&qpsp=94
Note how even MacOS has several times higher market share than Linux even though it is not free.
So please stop the flame war right now because this really isn’t the place to pile up junk off-topic comments.
JamesNT > If you’ve not read them already, read
http://www.kroah.com/log/linux/stable_api_nonsense.html
http://www.kroah.com/log/linux/ols_2006_keynote.html
Igor: Market share numbers prove nothing. Is a Ford better than a Ferrari?
Yep. Or a more appropiate one: Are automatic Digital Cameras better than manual traditional ones?
Average people can use DCs and take good photos in a short time, but you really need "to know something" before using a traditional one, of which every settings like focus or so must be tuned by yourself.
Having fewer people using traditional camera doesn’t prove one is inferior than the others or vice versa.
Reminds me of a problem we had to solve once. We needed a way of checking whether a COM server was still alive. The interface was already fixed, so an isAlive function wasn’t an option. My first attempt called QueryIterface(uuidof(IUnknown)) periodically, since that must succeed. Due to caching though, it continues to succeed when the server crashes. I finally ended up periodically querying for randomly-created GUIDs. E_NOINTERFACE meant the server was up, some other error meant the server was presumably down. Creating a new GUID each time kept the caching at bay.
I was wondering about this a quote from the ‘Rules for implementing QueryInterface’ page to which Raymond linked:
"For any given object instance, a call to QueryInterface(IID_IUnknown, …) must always return the same physical pointer value. This allows you to call QueryInterface(IID_IUnknown, …) on any two interfaces and compare the results to determine whether they point to the same instance of an object."
How exactly does one compare the two pointers and deduct whether they point to the same object or not?
I they point to two distinct entries in the interface table they are different, aren’t they?
Aleksander: That’s why you have to query for IUnknown. If you have a point to IInterface1 and another pointer to IInterface2, then even if its the same physical object, the pointers will necessarily be different. The IUnknown rule is there so that you can do a QueryInterface on each of IInterface1 and IInterface2, test the results of those and if THEY’RE equal, it’s the same object.
And to the people arguing over whether Linux or Windows is better, who cares? I’m in the business of selling software, so I’m going to concentrate my efforts on the platform that will result in the largest returns for my effort. If I had time to spare for Linux (or even Mac OS), I would, but my time is better spent where 95% of my potential customers are…
Stu said:
"Market share numbers prove nothing."
Those are the numbers for desktop OS market share and they prove the following:
A lot of them do so (like more than 90%)
You can conclude that either:
a) more than 90% of people are really stupid
b) less than 0.5% of people is really smart
c) Windows is not as bad when it comes to desktop use
d) Linux is not as good when it comes to desktop use
Circle all that apply. I personally vote for c) and d).
a) and b) choices are reserved for those who use the same type of reality distortion field as Mac users.
Stu said:
"Is a Ford better than a Ferrari?"
Cheong said:
"Are automatic Digital Cameras better than manual traditional ones?"
Yes and yes. They both have much better price/performance ratio for the majority of users.
If there’s one thing that annoys me, it’s COM objects that return E_FAIL for absolutely everything.
Even worse are apps that display them to the user.
Friend: Help, app X doesn’t work!
Me: What error are you getting?
App X: "Total everything failure: 0x80040005"
Me: That’s soooo not helpful.
Worst are apps that manage to display it in decimal instead of hex.
If anybody who reads this blog every has to implement a COM object: please, just take those extra thirty minutes and implement IErrorInfo.
Igor:
Or, Microsoft’s marketing machine is so good compared to the various Linux distributors that 90% of users do not realize there is an alternative, or believe that Windows is “good enough” (in many cases, it probably is, but in many of those, Linux would also be “good enough”, there just isn’t any great reason to switch).
Thus we can explain the “popularity” of Windows, without mentioning its quality or the intelligence of its users.
[What does this have to do with QueryInterface? -Raymond]
Nothing, sorry, went a bit off-topic there…
Yeah, going off topic is also my fault. I apologize, Mr. Chen.
James
I believe you can even have two IInterface2 pointers pointing to
different physical (C++) objects but representing the same logical
object.
I do so love it when even the most cosumer-oriented apps blurt out errors like that.
In fact I’m sure Media Player gives an almost identical error code when what it actually means is, "Unable to play this movie with your installed codecs, try downloading DivX or an AC3 audio codec." That was a fun bit of time on Google trying to get holiday videos playing for my mother.
(note please don’t take this as a "But even MS get it wrong" post, the error just stuck out of the screen at me and reminded me of this)
“Igor: Market share numbers prove nothing. Is a Ford better than a Ferrari?”
Stu: It’s about relevance, Windows is much more relevent than other OS’s. That is the point.
Stu said "Market share numbers prove nothing. Is a Ford better than a Ferrari?"
Well, the answer depends, like most real-world things. Fords are far better at moving off the lot in large quantities.