Работа с интерфейсом IDispatch

Тема в разделе "WASM.WIN32", создана пользователем pas, 20 мар 2005.

  1. pas

    pas New Member

    Публикаций:
    0
    Регистрация:
    18 апр 2003
    Сообщения:
    330
    Адрес:
    Russia
    Интерфейсы определен так:
    Код (Text):
    1.  
    2. ;IUnknown
    3. virtual at ebx
    4.   NameInterface#.IUnknown.QueryInterface dd 0
    5.   NameInterface#.IUnknown.AddRef dd 0
    6.   NameInterface#.IUnknown.Release dd 0
    7. end virtual
    8.  
    9. ;IDispatch
    10. virtual at ebx
    11.   NameInterface#.Disp.QueryInterface dd 0
    12.   NameInterface#.Disp.AddRef dd 0
    13.   NameInterface#.Disp.Release dd 0
    14.   NameInterface#.GetTypeInfoCount dd 0
    15.   NameInterface#.GetTypeInfo dd 0
    16.   NameInterface#.GetIDsOfNames dd 0
    17.   NameInterface#.Invoke dd 0
    18. end virtual
    19.  


    Далее создаю объект (Винворд) и получаю IUnknown
    Код (Text):
    1.  
    2. invoke CLSIDFromProgID,NameInterface#.RegKey,NameInterface#.GUID
    3. invoke CoCreateInstance,NameInterface#.GUID,0,5,IID_IUnknown,\
    4.                         NameInterface#.pvTable
    5. mov    eax,[NameInterface#.pvTable]
    6. mov    eax,[eax]
    7. mov    [NameInterface#.vTable],eax
    8.  
    9. затем получаю интерфейс IDispatch
    10.  
    11.        mov ebx,[NameInterface#.vTable]
    12.        stdcall [NameInterface#.IUnknown.AddRef],[NameInterface#.pvTable]
    13.        stdcall [NameInterface#.IUnknown.QueryInterface],[NameInterface#.pvTable],\
    14.                  IID_IDispatch,NameInterface#.Disp.pvTable
    15.        mov    eax,[NameInterface#.Disp.pvTable]
    16.        mov    eax,[eax]
    17.        mov    [NameInterface#.Disp.vTable],eax
    18.  
    19. Далее пытаюсь определить индекс метода AppSh du 'Exec',0
    20.  
    21.        mov ebx,[NameInterface#.Disp.vTable]
    22.        stdcall [NameInterface#.GetIDsOfNames],[NameInterface#.Disp.pvTable],\
    23.           0,AppSh,1,0,IDs
    24.  
    25.  


    Но в ответ получаю непонятный код ошибки 800706F4. Что бы это могло значить?
     
  2. amitophia

    amitophia New Member

    Публикаций:
    0
    Регистрация:
    28 мар 2004
    Сообщения:
    44
    Код (Text):
    1.  
    2. // MessageId: RPC_X_NULL_REF_POINTER
    3. //
    4. // MessageText:
    5. //
    6. //  A null reference pointer was passed to the stub.
    7. //
    8. #define RPC_X_NULL_REF_POINTER           1780L
     
  3. Avalonec

    Avalonec New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2004
    Сообщения:
    111
    Адрес:
    Тула
    Заместо 5 в CoCreateInstance, тебе, скорее всего, нужно использовать CLSCTX_INPROC_SERVER.



    AddRef тебе не нужно использовать здесь, т.к. она нужна во внутреннем устройстве метода.



    Довольно плохо читается. Советую использовать coinvoke.
     
  4. pas

    pas New Member

    Публикаций:
    0
    Регистрация:
    18 апр 2003
    Сообщения:
    330
    Адрес:
    Russia
    Avalonec



    Не помогает. Прийдется видимо дебажить прогу на Борл.С++ скомпиленую.
     
  5. amitophia

    amitophia New Member

    Публикаций:
    0
    Регистрация:
    28 мар 2004
    Сообщения:
    44
    pas

    Убедись, что IDs не равен NULL, а также попробуй вместо первого параметра передавать не 0, а указатель на структуру IID_NULL
     
  6. Avalonec

    Avalonec New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2004
    Сообщения:
    111
    Адрес:
    Тула
    Вот как, примерно, это должно выглядить:



    invoke CLSIDFromProgID,OF tx_reg_key,OF tx_name_GUID



    invoke CoCreateInstance,OF tx_name_GUID,NULL,CLSCTX_INPROC_SERVER,

    IID_IUnknown,OF x_1

    .if_succeeded



    com x_1,IUnknown.QueryInterface,IID_IDispatch,ADDR x_2



    mv lp_1,tx('Exec')

    com x_2,IID_IDispatch.GetIDsOfNames,NULL,OF lp_1,1,0,OF IDs



    .endif



    -----------------------



    HRESULT IDispatch::GetIDsOfNames(riid, rgszNames, cNames, lcid, rgdispid)

    REFIID riid

    OLECHAR FAR* FAR* rgszNames

    unsigned int cNames

    LCID lcid

    DISPID FAR* rgdispid
     
  7. amitophia

    amitophia New Member

    Публикаций:
    0
    Регистрация:
    28 мар 2004
    Сообщения:
    44
    pas

    Ещё обрати внимание, что в rgszNames должен передаваться массив строк, а не строка
     
  8. pas

    pas New Member

    Публикаций:
    0
    Регистрация:
    18 апр 2003
    Сообщения:
    330
    Адрес:
    Russia
    Спасибо, заработало. В смысле выдает ошибку, что такой процедуры нет. Но это уже не страшно.
     
  9. pas

    pas New Member

    Публикаций:
    0
    Регистрация:
    18 апр 2003
    Сообщения:
    330
    Адрес:
    Russia
    Странная вещь. Теперь если передавать ссылки на имена методов которые есть в интерфейсе сообщается об ошибке STATUS_ACCESS_VIOLATION equ 0C0000005h, а если передавать, что то от балды то DISP_E_UNKNOWNNAME equ 80020006h.

    Посмотрел STATUS_ACCESS_VIOLATION появляется в результате неудачи функций HeapReAlloc и HeapAlloc. Подскажите почему так происходит?
     
  10. bober

    bober New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2005
    Сообщения:
    153
    IID_NULL - это не нуль это указатель на структуру заполненую нулями. Имя должно быть юникодным. И указывай локализацию 400н если Typelib английский.
     
  11. pas

    pas New Member

    Публикаций:
    0
    Регистрация:
    18 апр 2003
    Сообщения:
    330
    Адрес:
    Russia


    Так и сделал.







    Попробую.
     
  12. pas

    pas New Member

    Публикаций:
    0
    Регистрация:
    18 апр 2003
    Сообщения:
    330
    Адрес:
    Russia
    „ И указывай локализацию 400н если Typelib английский.“

    К сожалению не помогает.
     
  13. bober

    bober New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2005
    Сообщения:
    153
    Вот этот код - у меня работает.

    Попробуй на своем компе, только нужно зарегистрировать (mswinsck.ocx). Если не будет работать тогда я пас :)







    ;#################################################



    .586

    .model flat, stdcall

    option casemap :none



    include \masm32\include\windows.inc

    include \masm32\include\user32.inc

    include \masm32\include\kernel32.inc

    include \masm32\include\ole32.inc



    includelib \masm32\lib\ole32.lib

    includelib \masm32\lib\user32.lib

    includelib \masm32\lib\kernel32.lib

    include oaidl.inc







    .data?

    szBuffer db 400 dup (?)

    .data

    IID_NULL GUID <0, 0, 0, <0, 0, 0, 0, 0, 0, 0, 0>>

    CLSID_Module GUID <0248DD896h, 0BB45h, 011CFh, <09Ah, 0BCh, 000h, 080h, 0C7h, 0E7h, 0B7h, 08Dh>>

    IID_IDispatch GUID <000020400H, 00000H, 00000H, <0C0H, 000H, 000H, 000H, 000H, 000H, 000H, 046H>>

    sztempl db "Disp ID for 'Bind' = %08X",0

    szCaption db "Hello :)",0

    NameID dd 0

    pMain dd 0

    rgszNames dd offset dwBind

    dwBind dw 'B','i','n','d', 0, 0, 0



    .code

    start:

    invoke OleInitialize, 0

    invoke CoCreateInstance, addr CLSID_Module, 0, CLSCTX_INPROC_SERVER, addr IID_IDispatch, addr pMain

    coinvoke pMain, IDispatch, GetIDsOfNames, addr IID_NULL, addr rgszNames, 1, 400h, addr NameID

    coinvoke pMain, IDispatch, Release

    invoke wsprintfA, addr szBuffer, addr sztempl, NameID

    invoke MessageBox, 0, addr szBuffer, addr szCaption, 0

    invoke ExitProcess, 0



    end start



    [​IMG] 78224065__ocxx.exe
     
  14. pas

    pas New Member

    Публикаций:
    0
    Регистрация:
    18 апр 2003
    Сообщения:
    330
    Адрес:
    Russia
    Спасибо большое, разобрался.