Как быть внутри библиотеки?
От: np9mi7 Россия  
Дата: 14.03.05 07:30
Оценка:
Добрый день. есть проблема. MFC советуют использовать вложение вместо наследования при реализации интерфейсов описанных в структурах, но как быть если внутри библиотеки необходимо добраться до члена класса за интерфейсом. Вот код:

struct ICar : public IUnknown
{
        virtual bool Move() = 0;
};
class CCar
{
        public:
               class XCar : public ICar
               {
                       public:
                              //
                              virtual HRESULT __stdcall QueryInterface        (const GUID &IID, void **ppv);
                              virtual ULONG   __stdcall AddRef                (void);
                              virtual ULONG   __stdcall Release               (void);
                              //
                              virtual bool Move();
               } m_xCar;
               friend class m_xRide ;
         const CArmchair& getArmchair();
         private:
                 CArmchair *m_pArmchair;
};
struct IPeopleInCar : public IUnknown
{
         virtual bool SeatToCard(const ICar&) = 0;
};
class CPeople
{
         public:
                class XPeopleInCar : IPeopleInCar
                {
                 //
                              virtual HRESULT __stdcall QueryInterface        (const GUID &IID, void **ppv);
                              virtual ULONG   __stdcall AddRef                (void);
                              virtual ULONG   __stdcall Release               (void);
                              //
                              virtual bool SeatToCard                         (const ICar&);
                } m_xPeopleInCar;
                friend class XPeopleInCar;
          private:
                  CPeople *m_pPeople;
                  CArmchair *m_pArmchair;
};

В данном случае пользователю библиотеки совершенно не хочеться знать что у человека жолжен быть внутри описано свойство КРЕСЛО, пользователь хочет лишь посадить человека в машину в которой он уже знает что есть за кресла...

КАК ДОБРАТЬСЯ ИЗ
virtual bool SeatToCard (const ICar&);

до
CArmchair *m_pArmchair;

в CCar...?
"В любое мгновение принятия решения, лучшее, что вы можете сделать, это принять правильное решение; следующим лучшим вариантом будет принять неправильное решение, худший вариант – не принимать решения совсем" (c) Теодор Рузвельт.
Re: Как быть внутри библиотеки?
От: Vi2 Удмуртия http://www.adem.ru
Дата: 14.03.05 08:56
Оценка:
Здравствуйте, np9mi7, Вы писали:

N>Добрый день. есть проблема. MFC советуют использовать вложение вместо наследования при реализации интерфейсов описанных в структурах, но как быть если внутри библиотеки необходимо добраться до члена класса за интерфейсом.


Посмотри макросы METHOD_PROLOGUE и пр. Из MSDN:
class CInnerUnknown : public IUnknown
   ...
   CInnerUnknown InnerUnknown;
   ...
// Inner IUnknown implementation 

   STDMETHODIMP_(ULONG) CInnerUnknown::AddRef()
   {
      METHOD_PROLOGUE(CCmdTarget, InnerUnknown)
      return pThis->InternalAddRef();
   }
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[2]: Как быть внутри библиотеки?
От: np9mi7 Россия  
Дата: 14.03.05 09:26
Оценка:
Здравствуйте, Vi2, Вы писали:

Vi2>Посмотри макросы METHOD_PROLOGUE и пр. Из MSDN:

Vi2>
Vi2>class CInnerUnknown : public IUnknown
Vi2>   ...
Vi2>   CInnerUnknown InnerUnknown;
Vi2>   ...
Vi2>// Inner IUnknown implementation 

Vi2>   STDMETHODIMP_(ULONG) CInnerUnknown::AddRef()
Vi2>   {
Vi2>      METHOD_PROLOGUE(CCmdTarget, InnerUnknown)
Vi2>      return pThis->InternalAddRef();
Vi2>   }
Vi2>

дело в том что этот макрос pThis устанавливает на IUnknown, когда this указывает на CInnerUnknown... У меня немного другая ситуация:

мне из
virtual bool SeatToCard (const ICar&)

— метод CPeople, нужно добраться до
CCar->getArmchair()


те зная объявление ССar (тк внутри библиотеки) + ICar — параметр (у которого есть реализация в этом классе, как она выглядет я не знаю — вложен класс) нужно добраться до
CCar->getArmchair()
"В любое мгновение принятия решения, лучшее, что вы можете сделать, это принять правильное решение; следующим лучшим вариантом будет принять неправильное решение, худший вариант – не принимать решения совсем" (c) Теодор Рузвельт.
Re[3]: Как быть внутри библиотеки?
От: Vi2 Удмуртия http://www.adem.ru
Дата: 14.03.05 09:52
Оценка:
Здравствуйте, np9mi7, Вы писали:

N>те зная объявление ССar (тк внутри библиотеки) + ICar — параметр (у которого есть реализация в этом классе, как она выглядет я не знаю — вложен класс) нужно добраться до
CCar->getArmchair()N>

Как-то так:
STDMETHODIMP_(bool) CPeople::XPeopleInCar::SeatToCard(/*[in]*/const ICar&)
{
    METHOD_PROLOGUE(CPeople, PeopleInCar)

    pThis->getArmchair(); // к функции, если позволит доступ
    pThis->m_pArmchair; // к данным, если позволит доступ
...
}
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[4]: Как быть внутри библиотеки?
От: np9mi7 Россия  
Дата: 14.03.05 10:03
Оценка:
Здравствуйте, Vi2, Вы писали:


N>>те зная объявление ССar (тк внутри библиотеки) + ICar — параметр (у которого есть реализация в этом классе, как она выглядет я не знаю — вложен класс) нужно добраться до
CCar->getArmchair()N>


Vi2>Как-то так:

Vi2>
Vi2>STDMETHODIMP_(bool) CPeople::XPeopleInCar::SeatToCard(/*[in]*/const ICar&)
Vi2>{
Vi2>    METHOD_PROLOGUE(CPeople, PeopleInCar)

Vi2>    pThis->getArmchair(); // к функции, если позволит доступ
Vi2>    pThis->m_pArmchair; // к данным, если позволит доступ
Vi2>...
Vi2>}
Vi2>



неа... тут Вы получите указатель pThis на CPeople->getArmchair()... а мне нужно на CCar->getArmchair()....
если вы заметили, CPeople->getArmchair() — вообще этого метода нет!

METHOD_PROLOGUE(CPeople, PeopleInCar) — он и поднимет pThis на CPeople, а мне нужно на CCar!!!
"В любое мгновение принятия решения, лучшее, что вы можете сделать, это принять правильное решение; следующим лучшим вариантом будет принять неправильное решение, худший вариант – не принимать решения совсем" (c) Теодор Рузвельт.
Re[5]: Как быть внутри библиотеки?
От: Vi2 Удмуртия http://www.adem.ru
Дата: 14.03.05 10:31
Оценка:
Здравствуйте, np9mi7, Вы писали:

N>неа... тут Вы получите указатель pThis на CPeople->getArmchair()... а мне нужно на CCar->getArmchair()....

N>если вы заметили, CPeople->getArmchair() — вообще этого метода нет!

N>METHOD_PROLOGUE(CPeople, PeopleInCar) — он и поднимет pThis на CPeople, а мне нужно на CCar!!!


Если между CPeople и CCar нет внутренней связи, то ответ — никак.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[6]: Как быть внутри библиотеки?
От: np9mi7 Россия  
Дата: 14.03.05 10:48
Оценка:
жаль...
ТЕ полюбому нужно както передавать параметрически... черт...
"В любое мгновение принятия решения, лучшее, что вы можете сделать, это принять правильное решение; следующим лучшим вариантом будет принять неправильное решение, худший вариант – не принимать решения совсем" (c) Теодор Рузвельт.
Re[7]: Как быть внутри библиотеки?
От: Vi2 Удмуртия http://www.adem.ru
Дата: 14.03.05 11:04
Оценка:
Здравствуйте, np9mi7, Вы писали:

N>жаль...

N>ТЕ полюбому нужно както передавать параметрически... черт...

Мысли в терминах интерфейсов. Нет необходимости выставлять интерфейс (т.е. публиковать), но пользоваться-то им можно и без этого. Тем более что это твои классы и твои интерфейсы. Создай интерфейс, по которому можно обратиться к реализации ICar (т.е. CCar) через ICar::QueryInterface(IID_Armchair,&pArmchair) и Armchair->getArmchair();
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[8]: Как быть внутри библиотеки?
От: np9mi7 Россия  
Дата: 14.03.05 11:49
Оценка:
Здравствуйте, Vi2, Вы писали:

Vi2>Мысли в терминах интерфейсов. Нет необходимости выставлять интерфейс (т.е. публиковать), но пользоваться-то им можно и без этого. Тем более что это твои классы и твои интерфейсы. Создай интерфейс, по которому можно обратиться к реализации ICar (т.е. CCar) через ICar::QueryInterface(IID_Armchair,&pArmchair) и Armchair->getArmchair();


ДА дело в том, что хотелось бы все эти вещи скрыть от пользователя. те, чтоб пользователь общался именно с теми интерфейсами которые я ему дам, не хотелось бы ему на верх отдавать КРЕСЛА...

Я вот думаю, может создать такой мега объект в котором описать как и МАШИНУ так и ЧЕЛОВЕКА В МАШИНЕ?
"В любое мгновение принятия решения, лучшее, что вы можете сделать, это принять правильное решение; следующим лучшим вариантом будет принять неправильное решение, худший вариант – не принимать решения совсем" (c) Теодор Рузвельт.
Re[9]: Как быть внутри библиотеки?
От: Vi2 Удмуртия http://www.adem.ru
Дата: 14.03.05 12:29
Оценка:
Здравствуйте, np9mi7, Вы писали:

N>ДА дело в том, что хотелось бы все эти вещи скрыть от пользователя. те, чтоб пользователь общался именно с теми интерфейсами которые я ему дам, не хотелось бы ему на верх отдавать КРЕСЛА...


Пользователь увидит лишь тот интерфейс у объекта, который описан в IDL/ODL/TLB файле для данного кокласса. Если там будет
    [uuid(XXXX),helpstring("XObject Class")]
    coclass XObject
    {
        [default] interface IUnknown;
    };
, то вообще неясно на какие интерфейсы будет откликаться этот объект. Также нет механизма, кроме описания кокласса в IDL/ODL/TLB файле, получения всех интерфейсов объекта. Потому что способ в СОМе прост: знаешь про интерфейс — запрашиваешь его у объекта. Если объект его понимает, то он отвечает, если не понимает, то возвращает код ошибки E_NOINTERFACE.

Более того, не каждый интерфейс, описанный в IDL/ODL файле, попадает в TLB файл. Если на интерфейс ничто в секции [library] не ссылается, то он в TLB не попадет, однако всегда попадет в H файл, генерируемый MIDLом. И поэтому твой сервер может спокойно работать с описанием этого интерфейса, знать его IID и т.п.

Единственная трудность при таком проектировании: нет описания интерфейса в TLB, значит, и нет typelib-маршаллинга интерфейса. Поэтому нужно предусматривать нахождение объектов в одном апартменте, что не всегда возможно, но почти всегда выполняется .
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[10]: Как быть внутри библиотеки?
От: np9mi7 Россия  
Дата: 14.03.05 13:58
Оценка:
да, действиетльно раз возникли такие заморочки, имеет смысл задаться вопросами нормального проектирования и постановки другого взгляда на задачу...

СПАСИБО ЗА ПОМОЩЬ!!!!!!
"В любое мгновение принятия решения, лучшее, что вы можете сделать, это принять правильное решение; следующим лучшим вариантом будет принять неправильное решение, худший вариант – не принимать решения совсем" (c) Теодор Рузвельт.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.