Наследяване от COM клас

Работя в Visual Studio 2005 с чист неуправляем проект (C++). Имам COM клас от трета страна в OCX файл. Този клас е контрола ("джаджа"). Използвал съм го чрез обвиващ клас IDispatch, генериран с помощта на Add Class от Typelib Wizard.

Бих искал да разширя този клас по няколко начина и публичното наследяване би било много по-практично от композирането (искам производният обект да излага всеки отделен метод, който прави родителският клас). Произведеният клас също трябва да бъде наличен като COM компонент.

Мога ли да направя това? Ако е положителен, как мога да постигна това?


person Vitor Py    schedule 01.08.2011    source източник


Отговори (2)


Не е възможно да наследите от COM класове, както можете в C++. Все пак има заобиколни решения:

COM агрегатите са полезни само ако искате да добавите интерфейс (с внедряване) към съществуващ COM клас. Не можете да прихващате повиквания към агрегирания обект.

Пренасочването означава, че ако имате интерфейс IExistingInterface, вие имплементирате свой собствен клас, който имплементира IExistingInterface. Във вашия клас поддържате препратка към екземпляр на обекта, от който искате да "наследите". Във вашето внедряване на IExistingInterface вие препращате повикванията според случая към „наследения“ обект. Този метод ви дава пълен контрол.

Пример: (псевдокод!)

class MyClass : IExistingInterface {
    IExistingInterface* m_pInherited;
public:
    MyClass() {
        ::CoCreateInstance(CLSID_OtherImplementation, ..., ..., IID_IExistingInterface, (void**)&m_pInherited);
    }

    // IExistingInterface methods
    HRESULT MethodX() {
        // Do some pre processing
        HRESULT hr = m_pInherited->MethodX();
        if(FAILED(hr))
            return hr;

        // Do some post processing
        return S_OK;
   }
};

Редактиране: Наистина ви препоръчвам да използвате ATL, за да създадете своя COM компонент. В такъв случай конструирайте "наследения" обект в FinalConstruct(), а не в C++ конструктора.

person Jörgen Sigvardsson    schedule 01.08.2011

Можете да създадете нов интерфейс, който произлиза от първия. Вашата функция QueryInterface ще трябва да отговори и на двата GUID и да достави правилния указател. След като направите това, накарайте вашия конкретен клас да внедри надмножеството от функции (т.е. целият втори интерфейс, включително всичко, наследено от първия.)

Ако вашият конкретен клас също ще наследява от конкретен клас в библиотеката, вие ще имате шаблон за наследяване на диамант. Можете да потърсите решения за това, бих започнал тук: Наследяване на диаманти (C++)

person Mark Ransom    schedule 01.08.2011