Не могу достучаться до ActiveX DLL через IDispatch

Раздел посвящен программированию с использованием Power Basic.
jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Не могу достучаться до ActiveX DLL через IDispatch

Сообщение jangle » 14.04.2009 (Вт) 22:37

Пытаюсь собрать COM DLL для юзанья из VBScript, код примерно такой:

Код: Выделить всё
#Compile Dll
#Dim All
#Optimize Speed
#Resource "winrar.pbr"
#Com Doc  "WinRAR archiver"    ' Description of the server
#Com Name "WinRARLib", 1.0   ' Server name and version number
#Com TLib On                       Generate a type library file
#Com Guid Guid$("{133A366D-A5A7-46F6-96D8-2CC9340CC24D}")             

Class Pack Guid$("{81B46121-5C65-4C0A-AB56-D04A83A32FD3}") As Com
  Interface IRar Guid$("{B466BC13-558B-4A20-96DA-2C5D267C59F8}") As Event
    Inherit IDispatch
    Method Compress Alias "Compress" (ByVal Param As String) As Long
    '...
    '...
    End Method
End Interface
End Class         


После компиляции, регистрации. Visual Studio видит этот COM-класс, и показывает его методы

Изображение

Однако, при запуске скрипта происходит ошибка:

Код: Выделить всё
Dim WinRar
SET WinRar=CreateObject ("PACK")
Сall WinRar.Compress ("TEXT TEXT")


Изображение

Не пойму, что за фигня такая? :(

BION
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 259
Зарегистрирован: 24.01.2005 (Пн) 21:05

Re: Не могу достучаться до ActiveX DLL через IDispatch

Сообщение BION » 15.04.2009 (Ср) 11:58

Мда. VB видит, метод вызывает, но через параметр доходит только первый символ стринга
Код: Выделить всё
    Dim w As New WinRARLib.PACK
    Call w.Compress("test")


C VBS то же самое. Причем
Код: Выделить всё
CreateObject( "WinRARLib.PACK" )
отказывается грузить.
Буээ!

karlex
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 138
Зарегистрирован: 30.03.2009 (Пн) 20:25
Откуда: Пермский край, г.Кунгур

Re: Не могу достучаться до ActiveX DLL через IDispatch

Сообщение karlex » 15.04.2009 (Ср) 12:06

BION писал(а):через параметр доходит только первый символ стринга

Может передавать нужно не в Unicode.

BION писал(а):CreateObject( "WinRARLib.PACK" )
отказывается грузить

Эм... А почему ты решил, что надо писать "WinRARLib.PACK" ?
Все гениальное — просто!
-------------------------------------
Кто ищет — тот всегда найдет!
-------------------------------------
Лень — двигатель прогресса.
Прогресс — двигатель лени.

BION
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 259
Зарегистрирован: 24.01.2005 (Пн) 21:05

Re: Не могу достучаться до ActiveX DLL через IDispatch

Сообщение BION » 15.04.2009 (Ср) 12:17

karlex писал(а):Эм... А почему ты решил, что надо писать "WinRARLib.PACK" ?


Потому что WinRARLib -- имя Com сервера. И так писать не обязательно, но все же, должно по идее работать.
Буээ!

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Не могу достучаться до ActiveX DLL через IDispatch

Сообщение jangle » 15.04.2009 (Ср) 12:28

BION писал(а):Мда. VB видит, метод вызывает, но через параметр доходит только первый символ стринга
Код: Выделить всё
    Dim w As New WinRARLib.PACK
    Call w.Compress("test")


C VBS то же самое. Причем
Код: Выделить всё
CreateObject( "WinRARLib.PACK" )
отказывается грузить.


Потому, что VB и VBS передают параметры в UNICODE, а функция в PB принимает их в ANSI. Перекодируй текст через ACode$.

BION
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 259
Зарегистрирован: 24.01.2005 (Пн) 21:05

Re: Не могу достучаться до ActiveX DLL через IDispatch

Сообщение BION » 15.04.2009 (Ср) 12:31

ой :oops:
Буээ!

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Не могу достучаться до ActiveX DLL через IDispatch

Сообщение jangle » 15.04.2009 (Ср) 12:35

Вобщем, через подключение через Reference из VB, COM класс работает прекрасно. Но если использовать позднее связывание, через CreateObject из VB или VBS - происходит ошибка. B главное, непонятно почему...

karlex
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 138
Зарегистрирован: 30.03.2009 (Пн) 20:25
Откуда: Пермский край, г.Кунгур

Re: Не могу достучаться до ActiveX DLL через IDispatch

Сообщение karlex » 15.04.2009 (Ср) 12:38

А верно ли следующее:
Выполняя CreateObject происходит (ну не совсем сразу же, но произойдет) поиск в реестре указанного Class в ветке HKCR, ведь именно в ней хранятся разделы с названиями: <project_name>.<coclass_name>, которые в свою очередь содержат подразделы, где можно найти CLSID этого самого CoClass.

После чего по найденному CLSID в разделе HKCR\CLSID\ происходит поиск раздела, имя которого = CLSID.

Когда будет найден нужный раздел, из него будет извлечен путь к модулю COM-сервера, по которому будет произведена дальнейшая загрузка модуля, создание нового объекта по CLSID и возвращение ссылки на созданный объект клиенту.

:?:

Если вышесказанное верно, то нужно убедиться правильно ли указан Class в CreateObject.

Если гоню, извините, я только-только начал углубляться в COM.
Все гениальное — просто!
-------------------------------------
Кто ищет — тот всегда найдет!
-------------------------------------
Лень — двигатель прогресса.
Прогресс — двигатель лени.

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Не могу достучаться до ActiveX DLL через IDispatch

Сообщение jangle » 15.04.2009 (Ср) 12:47

У меня в реестре запись о классе выглядет так. Это правильно?

Изображение

BION
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 259
Зарегистрирован: 24.01.2005 (Пн) 21:05

Re: Не могу достучаться до ActiveX DLL через IDispatch

Сообщение BION » 15.04.2009 (Ср) 12:57

В общем да.
Буээ!

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Не могу достучаться до ActiveX DLL через IDispatch

Сообщение jangle » 15.04.2009 (Ср) 12:58

Мне кажется, проблема в неправильных данных в реестре. Посмотрел другие COM DLL, у них в ветке InprocServer32 есть параметр ThreadingModel - Apartment. Может в этом дело?

karlex
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 138
Зарегистрирован: 30.03.2009 (Пн) 20:25
Откуда: Пермский край, г.Кунгур

Re: Не могу достучаться до ActiveX DLL через IDispatch

Сообщение karlex » 15.04.2009 (Ср) 13:06

jangle писал(а):У меня в реестре запись о классе выглядет так. Это правильно?

Ты же сам сказал, что объект создается, а ошибка происходит именно при обращении к его члену.
Если объект создается, значит правильно.

Только вот не может ли возникнуть коллизия имен?

PACK - довольно простое имя и сложно гарантировать, что уже нет такого же ProgID.

Как я понял, изучая различные источники, ну и убедившись на практике (ветка HKCR), ProgID должен иметь следующий вид:
<project_name>.<coclass_name>

Где project_name имя проекта соответственно, а coclass_name имя класса в нашем проекте (COM-сервере), т.е. в данном случае PACK.

Думаю все таки лучше придерживаться этих правил.

Мне кажется, проблема в неправильных данных в реестре. Посмотрел другие COM DLL, у них в ветке InprocServer32 есть параметр ThreadingModel - Apartment. Может в этом дело?

На счет ThreadingModel ни чего сказать не могу.

Но у меня появилась другая мысль, создай там раздел LocalServer32 с параметром по умолчанию равным пути к модулю сервера.
Честно говоря не совсем уверен в том, что я правильно понимаю назначение этого раздела, но попробовать можно.
Все гениальное — просто!
-------------------------------------
Кто ищет — тот всегда найдет!
-------------------------------------
Лень — двигатель прогресса.
Прогресс — двигатель лени.

BION
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 259
Зарегистрирован: 24.01.2005 (Пн) 21:05

Re: Не могу достучаться до ActiveX DLL через IDispatch

Сообщение BION » 15.04.2009 (Ср) 13:08

Присутствуют еще ветки TypeLib c GUID параметром.
Буээ!

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Не могу достучаться до ActiveX DLL через IDispatch

Сообщение jangle » 15.04.2009 (Ср) 13:15

karlex писал(а):
jangle писал(а):У меня в реестре запись о классе выглядет так. Это правильно?

Ты же сам сказал, что объект создается, а ошибка происходит именно при обращении к его члену.
Если объект создается, значит правильно.

Только вот не может ли возникнуть коллизия имен?

PACK - довольно простое имя и сложно гарантировать, что уже нет такого же ProgID.


Заменил имя класса и члена на сложные, результат тот же.

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Не могу достучаться до ActiveX DLL через IDispatch

Сообщение jangle » 15.04.2009 (Ср) 13:17

BION писал(а):Присутствуют еще ветки TypeLib c GUID параметром.


Действительно! Означает ли это, что надо каким-то образом регистрировать еще и TLB входящую в состав COM DLL?

BION
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 259
Зарегистрирован: 24.01.2005 (Пн) 21:05

Re: Не могу достучаться до ActiveX DLL через IDispatch

Сообщение BION » 15.04.2009 (Ср) 13:21

jangle писал(а):
BION писал(а):Присутствуют еще ветки TypeLib c GUID параметром.


Действительно! Означает ли это, что надо каким-то образом регистрировать еще и TLB входящую в состав COM DLL?


Возможно, но по идее это должно происходить автоматически при регистрации библиотеки.
Буээ!

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Не могу достучаться до ActiveX DLL через IDispatch

Сообщение jangle » 15.04.2009 (Ср) 13:30

Регистрация действительно должна быть автоматической...
А может, вся данная ситуация - просто глюк компилятора, который генерит кривую TLB? :?

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Не могу достучаться до ActiveX DLL через IDispatch

Сообщение jangle » 15.04.2009 (Ср) 13:54

Блин стыд и позор на мою голову! :mrgreen:
В коде и реестре все правильно, ошибка в VBScript - коде. В итоге все заработало правильно.

Dim WinRar
SET WinRar=CreateObject ("PACK")
Сall WinRar.Compress ("TEXT TEXT") < Call это -ошибка!

Надо так:

Код: Выделить всё
Dim WinRar, Result
SET WinRar=CreateObject ("PACK")
Result=WinRar.Compress ("TEXT TEXT")


Глюк из-за моей невнимательности :pale:

karlex
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 138
Зарегистрирован: 30.03.2009 (Пн) 20:25
Откуда: Пермский край, г.Кунгур

Re: Не могу достучаться до ActiveX DLL через IDispatch

Сообщение karlex » 15.04.2009 (Ср) 14:22

jangle писал(а):Call это -ошибка!
Надо так:
Result=WinRar.Compress ("TEXT TEXT")

Эм... А какое этому объяснение?
В VB вызов функции через Call вроде как нормально проходит, а тут такие грабли...
Все гениальное — просто!
-------------------------------------
Кто ищет — тот всегда найдет!
-------------------------------------
Лень — двигатель прогресса.
Прогресс — двигатель лени.

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Не могу достучаться до ActiveX DLL через IDispatch

Сообщение jangle » 15.04.2009 (Ср) 14:31

karlex писал(а):Эм... А какое этому объяснение?
В VB вызов функции через Call вроде как нормально проходит, а тут такие грабли...


Объяснение, пока не могу найти. Посмотрел IDL файл, там в возвращаемых параметрах стоит строчка:

Код: Выделить всё
[out, retval] long* );


Возможно должно быть:

Код: Выделить всё
[out, optional] long* );


Но однозначно не уверен.

Код winrar.tlb
Код: Выделить всё
// Generated .IDL file (by the OLE/COM Object Viewer)
//
// typelib filename: winrar.dll

[
  uuid(133A366D-A5A7-46F6-96D8-2CC9340CC24D),
  version(1.0),
  helpstring("WinRAR archiver")
]
library WinRARLib
{
    // TLib :     // TLib : OLE Automation : {00020430-0000-0000-C000-000000000046}
    importlib("stdole32.tlb");

    // Forward declare all types defined in this typelib
    interface IRAR;
    interface IRAR2;

    [
      odl,
      uuid(B466BC13-558B-4A20-96DA-2C5D267C59F8),
      helpstring("IRAR is a dual interface with VTable/Dispatch access."),
      dual,
      nonextensible,
      oleautomation
    ]
    interface IRAR : IDispatch {
        [id(0x00000101)]
        HRESULT Compress(
                        [in] BSTR PATH,
                        [in] BSTR ARCHPATH,
                        [in] BSTR PASSWORD,
                        [in] long LEVEL,
                        [out, retval] long* );
    };

    [
      odl,
      uuid(C3F05E0E-31FA-46A3-B161-B9631D387C62),
      helpstring("IRAR2 is a dual interface with VTable/Dispatch access."),
      dual,
      nonextensible,
      oleautomation
    ]
    interface IRAR2 : IDispatch {
        [id(0x00000102)]
        HRESULT Extract(
                        [in] BSTR RARARCHIVE,
                        [in] BSTR DESTPATH,
                        [in] BSTR PASSWORD,
                        [out, retval] long* );
    };

    [
      uuid(81B46121-5C65-4C0A-AB56-D04A83A32FD3)
    ]
    coclass RAR_PACK {
        [default] interface IRAR;
    };

    [
      uuid(B9562174-75F9-4C67-BEB3-4232D79425EB)
    ]
    coclass RAR_UNPACK {
        [default] interface IRAR2;
    };
};


Вернуться в Power Basic

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 21

    TopList