COM и MASM32

Тема в разделе "WASM.ASSEMBLER", создана пользователем psu, 12 янв 2007.

  1. psu

    psu New Member

    Публикаций:
    0
    Регистрация:
    12 июл 2006
    Сообщения:
    198
    Необходимо реализовать интерфейс, которій наследует IDispatch и IObjectWithSite. Возможно ли на masm?
     
  2. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Если это возможно на си, то почему нельзя на масме? Некоторые даже ActiveX на асме написали, что уж говорить о BHO :)
     
  3. psu

    psu New Member

    Публикаций:
    0
    Регистрация:
    12 июл 2006
    Сообщения:
    198
    В примерах масма посмотрел. В масме только IDispatch реализован, или я чего-то не понял?
     
  4. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Я о примерах ничего не говорил.
     
  5. nobodyzzz

    nobodyzzz New Member

    Публикаций:
    0
    Регистрация:
    13 июл 2005
    Сообщения:
    475
    А чем реализация IDispatch принципиально отличается от реализации IObjectWithSite? =)
     
  6. psu

    psu New Member

    Публикаций:
    0
    Регистрация:
    12 июл 2006
    Сообщения:
    198
    Ну пусть не в примерах. Слово IObjectWithSite встречается только в \masm32\com\include\bandobj.inc. Даже не знаю, как подступиться к этому на масме. В соседней ветке уже почти выяснил, как это написать на С++, но важен размер, потому необходимо переписать на масм. Помогите, кто знает, плз!!
     
  7. TheRawGod

    TheRawGod New Member

    Публикаций:
    0
    Регистрация:
    6 июл 2003
    Сообщения:
    71
    nobodyzzz

    IObjectWithSite и IDispatch - это вообще разные интерфейсы:)
    IObjectWithSite как и все СОМ интерфейсы, унаследоавн он IUnknown. К 3-м методам которого он добавляет 2 своих.
     
  8. psu

    psu New Member

    Публикаций:
    0
    Регистрация:
    12 июл 2006
    Сообщения:
    198
    Кто-то может пояснить, как вообще на масме это все делается? Смотрю пример MyCom2. Практически ничего не понятно. Можна пошагово расписать, как в этом примере IMyCom2 наследует IDispatch, и как к нему добавить наследование IObjectWithSite?
     
  9. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    На масме почти так же, как и на си. Читай теорию, на рсдн ряд хороших статей.
     
  10. psu

    psu New Member

    Публикаций:
    0
    Регистрация:
    12 июл 2006
    Сообщения:
    198
    Ну хоть убейте, не вижу на рсдн примеров на С. С++ только, и гугл молчит..
     
  11. Freeman

    Freeman New Member

    Публикаций:
    0
    Регистрация:
    10 фев 2005
    Сообщения:
    1.385
    Адрес:
    Ukraine
    На васме есть стотьи по СОМ :) Очень хорошие, с уклоном именно на ассемблер
     
  12. psu

    psu New Member

    Публикаций:
    0
    Регистрация:
    12 июл 2006
    Сообщения:
    198
    Прочитал. Не понятно, как создать интерфейс, который наследует более одного интерфейса. Вот, что уже написал:

    Код (Text):
    1. _vtIObjectWithSite MACRO CastName:REQ
    2.     _vtIUnknown CastName
    3.  
    4.     &CastName&_SetSite  comethod2 ?
    5.     &CastName&_GetSite  comethod3 ?
    6.  
    7. ENDM
    8.  
    9. IObjectWithSite         STRUC
    10.     _vtIObjectWithSite IObjectWithSite
    11. IObjectWithSite         ENDS
    12.  
    13. vtIDispatch         IDispatch       <   QueryInterface_MC,      \
    14.                                         AddRef_MC,              \
    15.                                         Release_MC,             \
    16.                                         GetTypeInfoCount,       \
    17.                                         GetTypeInfo,            \
    18.                                         GetIDsOfNames,          \
    19.                                         Invoke_                 \
    20.                                     >
    21. vtIObjectWithSite   IObjectWithSite <   QueryInterface_MC,      \
    22.                                 AddRef_MC,              \
    23.                                 Release_MC,             \
    24.                                 SetSite,                \
    25.                                 GetSite                 \
    26.                             >
    Правильно ли это? Есть две таблицы функций? Как тогда реализовать IClassFactory::CreateInstance?
     
  13. masquer

    masquer wasm.ru

    Публикаций:
    0
    Регистрация:
    13 сен 2002
    Сообщения:
    890
    Адрес:
    Николаев
    могу еще книгу InsideOLE 2 (Microsoft Press) порекомендовать, там именно потроха рассматриваются
     
  14. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Как угодно, в принципе - всё равно кастинг (приведение типов) будет через QueryInterface и ты можешь этим управлять. А вообще, в VC - это две vtbl, одна за другой.

    Смотришь на IID и возвращаешь нужный объект.
     
  15. psu

    psu New Member

    Публикаций:
    0
    Регистрация:
    12 июл 2006
    Сообщения:
    198
    Ну вот так например можна?

    Код (Text):
    1. MyComObject         STRUCT   ; this_
    2.     ; interface object
    3.     lpVtblIDispatch         DWORD   0
    4.     lpVtblIObjectWithSite   DWORD   0
    5.  
    6.     ; object data
    7.     nRefCount       DWORD       1  
    8. MyComObject         ENDS
    9.  
    10. ...
    11.  
    12. CreateMyComObject PROC
    13.     LOCAL   pNewObject:DWORD
    14.  
    15.     invoke  CoTaskMemAlloc, sizeof MyComObject
    16.     mov pNewObject, eax
    17.     .IF (eax != NULL)
    18.         mov edx, pNewObject
    19.         mov (MyComObject PTR [edx]).lpVtblIDispatch, OFFSET [b]vtIDispatch[/b]
    20.         mov (MyComObject PTR [edx]).lpVtblIObjectWithSite, OFFSET [b]vtIObjectWithSite[/b]
    21.         mov (MyComObject PTR [edx]).nRefCount, 1
    22.  
    23.     .ENDIF
    24.     mov eax, pNewObject
    25.     ret
    26. CreateMyComObject endp
    Тогда что нужно вернуть в QueryInterface_MC, если запрашивается IObjectWithSite? Просто смещение таблицы ее функций? А как тогда будет работать AddRef|Release? Непонятно, как реализовать счетчик. Люди добрые, ну пару строчек примера напишите, пожалуйста!!
     
  16. TheRawGod

    TheRawGod New Member

    Публикаций:
    0
    Регистрация:
    6 июл 2003
    Сообщения:
    71
    Правильно, просто смещение таблицы функций этого интерфейса.
    AddRef / Release / QueryInterface реализованы все один раз. Все vtable содержат ссылки на одну и ту же реализацию.
    Можно, в принципе, и не один раз, как угодно можно выворачиваться (если зачем-то нужно:)).

    Да вот, даже в одном из Ваших постов выше Вы использовали, например, AddRef_MC и для IObjectWithState, и для IDispatch.
     
  17. psu

    psu New Member

    Публикаций:
    0
    Регистрация:
    12 июл 2006
    Сообщения:
    198
    Ну вот смотрите.

    Код (Text):
    1. MyComObject         STRUCT   ; this_
    2.  
    3.     lpVtblIDispatch     DWORD   0
    4.     lpVtblIObjectWithSite   DWORD   0
    5.  
    6.     nRefCount       DWORD       1  
    7. MyComObject         ENDS
    если при запросе IObjectDispatch я верну lpVtblIObjectWithSite из QueryInterface_MC, то this_ при вызове AddRef_MC будет указывать на экземпляр MyComObject, смещенный на 4 байта, соответственно, счетчик будет находиться за пределами обьекта. Вот чего я не понимаю. Ведь счетчик-то общий и для IDispatch и для IObjectWithSite.
     
  18. TheRawGod

    TheRawGod New Member

    Публикаций:
    0
    Регистрация:
    6 июл 2003
    Сообщения:
    71
    Счетчик должен быть либо "корректно" размещен относительно AddRef_MC, либо указатель на него должен быть туда передан.
    Если не нужны выверты, то используется первый случай. Т.е. реализация AddRef_MC у нас одна, в самом классе объекта, значит this при заходе в нее будет указывать именно на объект.

    То, что QueryInterface вернет указатель на vtable одного из интерфесов совсем не значит, что внутри реализации методов этого интерфеса при их вызове this будет указывать на этот же vtable:) This указывает на объект, в котором реализована функция этот this используящая. А так как все методы в Вашем случае реализованы на MyComObject, то все ссылки будут "правильными".

    Последний абзац можно упрощенно резюмировать так: "откуда" бы Вы не зашли в AddRef_MC, this внутри него будет ссылаться на объект, в котором AddRef_MC реализован.
     
  19. psu

    psu New Member

    Публикаций:
    0
    Регистрация:
    12 июл 2006
    Сообщения:
    198
    Вот кусок кода из QueryInterface_MC

    Код (Text):
    1. invoke  IsEqualGUID, pRIID, addr IID_IObjectWithSite
    2. .IF eax == TRUE
    3.         mov eax, this_
    4.             mov eax, (MyComObject PTR [eax]).lpVtblIObjectWithSite       ???????????????? правильно
    5.             mov edx, ppv
    6.             mov [ edx ], eax
    7.         invoke AddRef_MC, this_  ; inc the ref count for the new pointer *we* created    
    8.  
    9.             mov eax, S_OK           ; and signal all is well           
    10.             jmp return
    11. .ENDIF
    в таком виде бразуер падает после первого же запроса IID_IObjectWithSite. Если закоментить помеченную строку, то грузиться все нормально, но SetSite и GetSite не вызываются. Запросов на IID_IDispatch вообще не поступает.

    Если поменять местами lpVtblIObjectWithSite и lpVtblIDispatch в обьявлении MyComObject, то начинает работать, вызывается и SetSite и GetSite.
     
  20. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    psu
    Сделай два разных объекта, по QI возвращай нужный. Или пиши вручную объект, без макросов - чем возиться и гадать, как же извернуться и сделать две v-table.