我正在开发一个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)
?
答案 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并通告已实现的接口。