Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is COM interface name replaced by coclass name in VB6?

Tags:

c++

com

vb6

I am developing a C++ COM library to use it from a VB6 application. The .IDL file defines a few interfaces and a class library with some component classes that implement these interfaces:

[
    local,
    object,
    uuid(....),
    version(1.0)
]
interface ICOMCvPixelBuffer : IUnknown
{
    ....
};

[
    local,
    object,
    uuid(....),
    version(1.0)
]
interface ICOMCvBitmap : IUnknown
{
    ....
    HRESULT GetPixelBuffer([retval][out] ICOMCvPixelBuffer** pBuffer);
    HRESULT SetPixelBuffer([in] ICOMCvPixelBuffer* pBuffer);
    ....
};

[
    uuid(....),
    version(1.0)
]
library COMCvLibrary
{
    importlib("stdole32.tlb");
    interface ICOMCvBitmap;
    interface ICOMCvPixelBuffer;

    [
        uuid(....),
        version(1.0)
    ]
    coclass CCOMCvPixelBuffer
    {
        [default] interface ICOMCvPixelBuffer;
    };

    [
        uuid(....),
        version(1.0)
    ]
    coclass CCOMCvBitmap
    {
        [default] interface ICOMCvBitmap;
    };
};

The Object Browser in VB6 shows the definition of the SetPixelBuffer method of the CCOMCvBitmap class as Sub SetPixelBuffer(pBuffer As CCOMCvPixelBuffer).

Why it is not Sub SetPixelBuffer(pBuffer As ICOMCvPixelBuffer) as declared in .IDL?

like image 587
ezpresso Avatar asked Sep 25 '11 20:09

ezpresso


2 Answers

Finally I found out an answer to my question.

As I understood from the book ".NET and COM: The Complete Interoperability Guide", if the coclass's default interface is defined in the same class library as the coclass, the VB6's type library importer replaces any parameters and the fields of the default interface type with the coclass type.

Also, a helpful information on the mechanics that stands behind the VB6 can be found here:

Visual Basic uses the class module name as an alias for the default interface; that is, the Visual Basic compiler maps the class name to the default interface reference silently for you.

One of the working solution is to supply IUnknown as the default interface of the CCOMCvPixelBuffer coclass:

[
    uuid(....),
    version(1.0)
]
coclass CCOMCvPixelBuffer
{
    [default] interface IUnknown;
    interface ICOMCvPixelBuffer;
};
like image 173
ezpresso Avatar answered Oct 07 '22 06:10

ezpresso


As far as I remember, VB6 does not like the idea that COM object implements 2+ automation interfaces. Along with this, if it implements one, then it quite assumable that the interface is implemented by coclass which is declared as implementing this interface:

coclass CCOMCvBitmap { [default] interface ICOMCvBitmap;

This way VB6 might be making it simpler for VB6 developer undestanding, trying to explain the working using objects rather than interfaces.

If you are curios for an experiment, try to comment the line "[default] interface ICOMCvBitmap;" above and see if VB6 will show the type as interface. This should not break interoperation, as your ATL implementation object will still implement IProvideClassInfo and advertise implemented interface.

like image 28
Roman R. Avatar answered Oct 07 '22 07:10

Roman R.