Почему имя интерфейса COM заменяется на имя класса в VB6? - PullRequest
3 голосов
/ 26 сентября 2011

Я разрабатываю 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).

Почему это не Sub SetPixelBuffer(pBuffer As ICOMCvPixelBuffer), как объявлено в .IDL?

Ответы [ 2 ]

3 голосов
/ 27 сентября 2011

Наконец я нашел ответ на свой вопрос.

Как я понял из книги ". NET и COM: Полное руководство по взаимодействию" , если задан интерфейс по умолчанию для Coclassв той же библиотеке классов, что и кокласс, импортер библиотеки типов VB6 заменяет любые параметры и поля типа интерфейса по умолчанию типом кокласса.

Кроме того, полезная информация о механике, стоящей за VB6, можетбыть найденным здесь :

Visual Basic использует имя модуля класса в качестве псевдонима для интерфейса по умолчанию;то есть компилятор Visual Basic автоматически сопоставляет имя класса со ссылкой на интерфейс по умолчанию.

Одним из рабочих решений является предоставление IUnknown в качестве интерфейса по умолчанию для класса CCOMCvPixelBuffer.:

[
    uuid(....),
    version(1.0)
]
coclass CCOMCvPixelBuffer
{
    [default] interface IUnknown;
    interface ICOMCvPixelBuffer;
};
2 голосов
/ 26 сентября 2011

Насколько я помню, VB6 не нравится идея, что COM-объект реализует 2+ интерфейса автоматизации. Наряду с этим, если он реализует один, то вполне возможно, что интерфейс реализован с помощью coclass, который объявлен как реализующий этот интерфейс:

кокласс CCOMCvBitmap { [по умолчанию] интерфейс ICOMCvBitmap;

Таким образом, VB6 может упростить понимание для разработчика VB6, пытаясь объяснить работу с использованием объектов, а не интерфейсов.

Если вы любите эксперимент, попробуйте прокомментировать строку «[default] interface ICOMCvBitmap;» выше и посмотрите, будет ли VB6 показывать тип как интерфейс. Это не должно нарушать взаимодействие, так как ваш объект реализации ATL будет по-прежнему реализовывать IProvideClassInfo и рекламировать реализованный интерфейс.

...