为什么在VB6中用coclass名称替换COM接口名称?

时间:2011-09-25 20:31:22

标签: c++ com vb6

我正在开发一个C ++ COM库,以便从VB6应用程序中使用它。 .IDL文件定义了一些接口和一个类库,其中包含一些实现这些接口的组件类:

[
    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;
    };
};

VB6中的对象浏览器将SetPixelBuffer类的CCOMCvBitmap方法的定义显示为Sub SetPixelBuffer(pBuffer As CCOMCvPixelBuffer)

为什么在.IDL中声明不是Sub SetPixelBuffer(pBuffer As ICOMCvPixelBuffer)

2 个答案:

答案 0 :(得分:3)

最后我找到了问题的答案。

正如我从书".NET and COM: The Complete Interoperability Guide"中所理解的那样,如果coclass的默认接口与coclass在同一个类库中定义,则VB6的类型库导入器会将所有参数和默认接口类型的字段替换为coclass类型。

此外,可以找到有关VB6背后的机制的有用信息here

  

Visual Basic使用类模块名称作为默认接口的别名;也就是说,Visual Basic编译器会为您静默地将类名映射到默认接口引用。

其中一个有效的解决方案是提供IUnknown作为CCOMCvPixelBuffer coclass的默认界面:

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

答案 1 :(得分:2)

据我记忆,VB6不喜欢COM对象实现2+自动化接口的想法。除此之外,如果它实现了一个,那么可以认为接口是由coclass实现的,它被声明为实现了这个接口:

  

coclass CCOMCvBitmap   {     [默认]界面ICOMCvBitmap;

这样VB6可能会让VB6开发人员更加简单,试图解释使用对象而不是接口的工作。

如果您是实验的好奇心,请尝试注释“[default] interface ICOMCvBitmap;”上面看看VB6是否会将类型显示为接口。这不应该破坏互操作性,因为您的ATL实现对象仍将实现IProvideClassInfo并通告已实现的接口。