Returning undocumented HRESULTS from standard COM interface methods?
What is the rule on returning undocumented HRESULTS from documented standard COM objects?
i'm looking at the documentation for IObjectWithSite.SetSite
, which says i should return S_OK
in all situations:
Syntax
HRESULT SetSite(IUnknown *pUnkSite);
Parameters
- pUnkSite: [in] An interface pointer to the site managing this object. If NULL, the object should call IUnknown::Release to release the existing site.Return Value
Returns S_OK in all circumstances.
Which is fine. But then i'm looking at an MSDN article detailing writing a Browser Helper Object, and there is his code for IObjectWithSite.SetSite
, and it returns HRESULTS other than S_OK:
E_INVALIDARG
if pUnkSite is NULLE_INVALIDARG
if开发者_如何转开发 pUnkSite does not supportIWebBrowser2
E_POINTER
if webBrowser does not supportIConnectionPointContainer
- result of event connection otherwise (i.e.
S_OK
)
HRESULT CViewSource::SetSite(IUnknown *pUnkSite) { // Retrieve and store the IWebBrowser2 pointer m_spWebBrowser2 = pUnkSite; if (m_spWebBrowser2 == NULL) return E_INVALIDARG; // Retrieve and store the IConnectionPointerContainer pointer m_spCPC = m_spWebBrowser2; if (m_spCPC == NULL) return E_POINTER; // Retrieve and store the HWND of the browser. Plus install // a keyboard hook for further use RetrieveBrowserWindow(); // Connect to the container for receiving event notifications return Connect(); }
The fact that the code returns E_INVALIDARG
if pUnkSite is NULL looks like a bug, the documentation specifically says that the parameter can be null.
The documentation doesn't mention any other HRESULTS as possible return values - in fact it says that S_OK
is to be returned in all circumstances?
Surely they can't be serious; they can't mean all circumstances. Right? What if there's an out-of-memory condition, or memory protection fault because someone pulled out a RAM stick?
What is the rule on returning undocumented HRESULTS from documented standard COM objects?
When you do COM programming, you are in general very defensive. So, as a caller, you use the famous FAILED or SUCCEEDED macros (or equivalent in the language used) when calling functions of an interface.
However, when the documentation stipulates that the result is not important, it is recommended not to check the result. So, as a caller, I would do
...
myObject.SetSite(whatever);
...
instead of
...
if (FAILED(myObject.SetSite(whatever))) goto error;
...
Note this is quite specific because SetSite is documented like this.
If I don't read the doc carefully (as you did) and assume this is a "regular hresult return" interface call, I would use the FAILED macro. If you return anything undocumented, FAILED will catch it anyway, and I'm quite safe anyway.
精彩评论