Question about dispinterface

Question about dispinterface

Post by Alexander Nickolo » Wed, 12 Feb 2003 12:08:17



You are completely wrong. "A dispinterface doesn't have vtable" means
vtable entries for its methods. It does have a vtable for the 7 IDispatch
methods. I can implement an entire dispinterface in exactly one method
of a C++ class - the implementation of IDispatch::Invoke. Sure it'll be
long and ugly as hell, but it's possible. A more common approach is to
use table-driven IDispatch implementation (like for example ATL's
IDispEvent[Simple]Impl) where the Invoke implementation scans a table
and invokes a method when it finds its DISPID in the table. The method
is typically non-virtual and doesn't register in any vtables.

I suspect you mistake dual interfaces for dispinterfaces. They are not
the same - you should be aware of that. A dual interface is a binding
between a dispinterface and a COM interface deriving from IDispatch.
The binding contract states that the functionality exposed through
the vtable portion (above the 7 IDispatch methods) of the COM interface
must be equivalent to what is available through the dispinterface
implemented via that particular IDispatch (e.g. IDispatch::Invoke).

--
=====================================
Alexander Nickolov
Microsoft MVP [VC], MCSD

MVP VC FAQ: http://www.mvps.org/vcfaq
=====================================


> Hi,

> I am struggling to understand the following statement:

> "...a dispinterface doesn't have a vtable"
> - Understanding Interface Definition Language: A Developer's Survival Guide
> by Bill Hludzinski

> Well, every class that has a virtual method must have a vtable in C++.  So
> how does this fit in C++ realm?  What I *think* it means is that it does
> have a vtable, just extra methods tacked on that allow access by an index
> (otherwise known as a DISPID).  Correct me if I'm wrong?

> Thanks!

 
 
 

Question about dispinterface

Post by Alexander Nickolo » Thu, 13 Feb 2003 07:50:41


You still confuse a dispinterface with a COM interface (which I suppose you
confuse in turn with a C++ class...). A dispinterface is a contract that the
implementing COM object (note no mention of C++ classes here!) will
implement the 7 IDispatch methods to expose the described functionality.
It has semantics, but its syntax is limited to the 7 IDispatch methods only.
Here's a sample that should hopefully make things clearer:

dispinterface DSomething
{
    properties:
    methods:
        [id(1)] void Something();

Quote:}

// In your C++ class implementation
STDMETHODIMP CMyObj::GetIDsOfNames(
    REFIID  riid,                  
    OLECHAR FAR* FAR*  rgszNames,  
    unsigned int  cNames,          
    LCID   lcid,                  
    DISPID FAR*  rgDispId)
{
    // Error checking first - skipped for brevity
    if (lstrcmpiW(rgszNames[0], L"Something") == 0) {
        // *** This links the method name to its DISPID ***
        rgDispId[0] = 1;
    } else {
        return DISP_E_MEMBERNOTFOUND;
    }
    return S_OK;

Quote:}

STDMETHODIMP CMyObj::Invoke(
    DISPID dispIdMember,
    REFIID riid,
    LCID lcid,
    WORD wFlags,
    DISPPARAMS FAR *pDispParams,
    VARIANT FAR *pVarResult,
    EXCEPINFO FAR *pExcepInfo,
    unsigned int FAR *puArgErr
)
{
    // Error checking first - skipped for brevity
    switch (dispidMember) {
    // *** Here the DISPID gets its implementation ***
    case 1:
        // Do whatever the method has to do here
        ::MessageBoxW(NULL, L"Method Something()", L"MyObj", MB_OK | MB_ICONINFORMATION);
        return S_OK;
    }
    return DISP_E_MEMBERNOTFOUND;

Quote:}

This is a fairly complete implementation of the above dispinterface.
And no vtable entries for anything but the IDispatch methods anywhere
in sight. Do you get it now?

An additional reading you'll find even more enlightening is chapters
14 and 15 of "Inside OLE" by Kraig Brockschmidt.

--
=====================================
Alexander Nickolov
Microsoft MVP [VC], MCSD

MVP VC FAQ: http://www.mvps.org/vcfaq
=====================================


> Thank-you Alexander, it's much clearer now.  So what you're saying is that a
> dispinterface has vtable entries for the 7 methods of IDispatch, and the
> rest of the "custom" defined methods do not.  To access the custom methods,
> you get the dispid and go through IDispatch::Invoke(...) etc...

> What i'm still not clear of is why the custom methods would not have vtable
> entries?  Given a definition such as:

> dispinterface MyDispInterface {
>   properties:
>     ....
>   methods:
>   [id(3)] HRESULT meth1();
>   [id(3)] HRESULT meth2();
> }

> won't meth1 and meth2 have vtable entries, since in C++ the methods will be
> generated as pure virtual?  In which case it becomes a dual
> interface........obviously i'm missing something here :-)

> Thanks again,

> Roy



> You are completely wrong. "A dispinterface doesn't have vtable" means
> vtable entries for its methods. It does have a vtable for the 7 IDispatch
> methods. I can implement an entire dispinterface in exactly one method
> of a C++ class - the implementation of IDispatch::Invoke. Sure it'll be
> long and ugly as hell, but it's possible. A more common approach is to
> use table-driven IDispatch implementation (like for example ATL's
> IDispEvent[Simple]Impl) where the Invoke implementation scans a table
> and invokes a method when it finds its DISPID in the table. The method
> is typically non-virtual and doesn't register in any vtables.

> I suspect you mistake dual interfaces for dispinterfaces. They are not
> the same - you should be aware of that. A dual interface is a binding
> between a dispinterface and a COM interface deriving from IDispatch.
> The binding contract states that the functionality exposed through
> the vtable portion (above the 7 IDispatch methods) of the COM interface
> must be equivalent to what is available through the dispinterface
> implemented via that particular IDispatch (e.g. IDispatch::Invoke).

> --
> =====================================
> Alexander Nickolov
> Microsoft MVP [VC], MCSD

> MVP VC FAQ: http://www.mvps.org/vcfaq
> =====================================



> > Hi,

> > I am struggling to understand the following statement:

> > "...a dispinterface doesn't have a vtable"
> > - Understanding Interface Definition Language: A Developer's Survival
> Guide
> > by Bill Hludzinski

> > Well, every class that has a virtual method must have a vtable in C++.  So
> > how does this fit in C++ realm?  What I *think* it means is that it does
> > have a vtable, just extra methods tacked on that allow access by an index
> > (otherwise known as a DISPID).  Correct me if I'm wrong?

> > Thanks!


 
 
 

Question about dispinterface

Post by Alexander Nickolo » Thu, 13 Feb 2003 11:38:51


Well, they are methods in the dispinterface. Did I say already you
confuse interfaces with C++ classes :).

--
=====================================
Alexander Nickolov
Microsoft MVP [VC], MCSD

MVP VC FAQ: http://www.mvps.org/vcfaq
=====================================


> YES!!!!  I do....that example did wonders.  So these methods of the
> dispinterface are not actual methods - they just represent an "index" to a
> single Invoke method.....right?

> Thanks for clearing that up.  You rule!



> You still confuse a dispinterface with a COM interface (which I suppose you
> confuse in turn with a C++ class...). A dispinterface is a contract that the
> implementing COM object (note no mention of C++ classes here!) will
> implement the 7 IDispatch methods to expose the described functionality.
> It has semantics, but its syntax is limited to the 7 IDispatch methods only.
> Here's a sample that should hopefully make things clearer:

> dispinterface DSomething
> {
>     properties:
>     methods:
>         [id(1)] void Something();
> }

> // In your C++ class implementation
> STDMETHODIMP CMyObj::GetIDsOfNames(
>     REFIID  riid,
>     OLECHAR FAR* FAR*  rgszNames,
>     unsigned int  cNames,
>     LCID   lcid,
>     DISPID FAR*  rgDispId)
> {
>     // Error checking first - skipped for brevity
>     if (lstrcmpiW(rgszNames[0], L"Something") == 0) {
>         // *** This links the method name to its DISPID ***
>         rgDispId[0] = 1;
>     } else {
>         return DISP_E_MEMBERNOTFOUND;
>     }
>     return S_OK;
> }

> STDMETHODIMP CMyObj::Invoke(
>     DISPID dispIdMember,
>     REFIID riid,
>     LCID lcid,
>     WORD wFlags,
>     DISPPARAMS FAR *pDispParams,
>     VARIANT FAR *pVarResult,
>     EXCEPINFO FAR *pExcepInfo,
>     unsigned int FAR *puArgErr
> )
> {
>     // Error checking first - skipped for brevity
>     switch (dispidMember) {
>     // *** Here the DISPID gets its implementation ***
>     case 1:
>         // Do whatever the method has to do here
>         ::MessageBoxW(NULL, L"Method Something()", L"MyObj", MB_OK |
> MB_ICONINFORMATION);
>         return S_OK;
>     }
>     return DISP_E_MEMBERNOTFOUND;
> }

> This is a fairly complete implementation of the above dispinterface.
> And no vtable entries for anything but the IDispatch methods anywhere
> in sight. Do you get it now?

> An additional reading you'll find even more enlightening is chapters
> 14 and 15 of "Inside OLE" by Kraig Brockschmidt.

> --
> =====================================
> Alexander Nickolov
> Microsoft MVP [VC], MCSD

> MVP VC FAQ: http://www.mvps.org/vcfaq
> =====================================



> > Thank-you Alexander, it's much clearer now.  So what you're saying is that
> a
> > dispinterface has vtable entries for the 7 methods of IDispatch, and the
> > rest of the "custom" defined methods do not.  To access the custom
> methods,
> > you get the dispid and go through IDispatch::Invoke(...) etc...

> > What i'm still not clear of is why the custom methods would not have
> vtable
> > entries?  Given a definition such as:

> > dispinterface MyDispInterface {
> >   properties:
> >     ....
> >   methods:
> >   [id(3)] HRESULT meth1();
> >   [id(3)] HRESULT meth2();
> > }

> > won't meth1 and meth2 have vtable entries, since in C++ the methods will
> be
> > generated as pure virtual?  In which case it becomes a dual
> > interface........obviously i'm missing something here :-)

> > Thanks again,

> > Roy



> > You are completely wrong. "A dispinterface doesn't have vtable" means
> > vtable entries for its methods. It does have a vtable for the 7 IDispatch
> > methods. I can implement an entire dispinterface in exactly one method
> > of a C++ class - the implementation of IDispatch::Invoke. Sure it'll be
> > long and ugly as hell, but it's possible. A more common approach is to
> > use table-driven IDispatch implementation (like for example ATL's
> > IDispEvent[Simple]Impl) where the Invoke implementation scans a table
> > and invokes a method when it finds its DISPID in the table. The method
> > is typically non-virtual and doesn't register in any vtables.

> > I suspect you mistake dual interfaces for dispinterfaces. They are not
> > the same - you should be aware of that. A dual interface is a binding
> > between a dispinterface and a COM interface deriving from IDispatch.
> > The binding contract states that the functionality exposed through
> > the vtable portion (above the 7 IDispatch methods) of the COM interface
> > must be equivalent to what is available through the dispinterface
> > implemented via that particular IDispatch (e.g. IDispatch::Invoke).

> > --
> > =====================================
> > Alexander Nickolov
> > Microsoft MVP [VC], MCSD

> > MVP VC FAQ: http://www.mvps.org/vcfaq
> > =====================================



> > > Hi,

> > > I am struggling to understand the following statement:

> > > "...a dispinterface doesn't have a vtable"
> > > - Understanding Interface Definition Language: A Developer's Survival
> > Guide
> > > by Bill Hludzinski

> > > Well, every class that has a virtual method must have a vtable in C++.
> So
> > > how does this fit in C++ realm?  What I *think* it means is that it does
> > > have a vtable, just extra methods tacked on that allow access by an
> index
> > > (otherwise known as a DISPID).  Correct me if I'm wrong?

> > > Thanks!

 
 
 

1. dispinterface question

I have created ole automation Exe server in MFC using
VStudio 6.0. This creates by default IMyDispatch
interface which is in idl file as "dispinterface
IMyDispatch"

Now on the client side, when I import the typelibray and
try to get IMyDispatch interface, I get an error saying
the server doesn't support this interface. Note, if I
query for IUnknown or IDispatch interface it works fine.
What am I missing?

Thanks,

2. Test

3. MIDL dispinterface source method doesn't line size_is.

4. xInfo - 1800+ Information sources/Screen saver/Agent technology

5. array of shorts in dispinterface

6. Newbie: Manuf. System Modeling

7. Why are dispinterfaces used for events ?

8. How to print CodeWarrior books on CD?

9. mapping custom dispinterface to IDispatch?

10. passing arrays in dispinterface

11. Automation server with only dispinterface? without a typelib?

12. Q: Returning HRESULT from a dispinterface method

13. which dispinterface is a source?