Раннее и позднее связывание...

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Vovik
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 643
Зарегистрирован: 02.08.2003 (Сб) 15:14
Откуда: Belarus, Minsk

Раннее и позднее связывание...

Сообщение Vovik » 11.04.2005 (Пн) 17:49

Привидите пож-ста маленький пример позднего связывания....
На сколько оно тормозит выполнение программы? :roll:

FaKk2
El rebelde gurú
El rebelde gurú
Аватара пользователя
 
Сообщения: 2031
Зарегистрирован: 09.03.2003 (Вс) 22:10
Откуда: Los Angeles

Сообщение FaKk2 » 11.04.2005 (Пн) 18:34

Код: Выделить всё

Dim obj as Excel.Application
Set obj=New Excel.Application


Вроде так.
Насчет скорости не в курсе.
Для получения ответа надо продемонстрировать качества, позволяющие стать компетентным — внимательность, вдумчивость, наблюдательность, желание активно участвовать в выработке решения.

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 11.04.2005 (Пн) 18:48

Это как раз раннее.
Код: Выделить всё
dim a as object
set a=createobject("Excel.Application")


Само по себе связывание делает всего лишь на один вызов QueryInterface больше, чем раннее. Но вот использование IDispatch заместо vtable весьма существенно снижает производительность.
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

Vovik
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 643
Зарегистрирован: 02.08.2003 (Сб) 15:14
Откуда: Belarus, Minsk

Сообщение Vovik » 11.04.2005 (Пн) 21:12

ANDLL писал(а):Это как раз раннее.
Код: Выделить всё
dim a as object
set a=createobject("Excel.Application")


Само по себе связывание делает всего лишь на один вызов QueryInterface больше, чем раннее. Но вот использование IDispatch заместо vtable весьма существенно снижает производительность.
А можно чуть-чуть подробнее, а то я в этих делах как-то несильно шарю.. :roll:

Ennor
Конструктивный критик
Конструктивный критик
 
Сообщения: 2504
Зарегистрирован: 18.12.2001 (Вт) 3:58
Откуда: Калуга -> Москва

Сообщение Ennor » 11.04.2005 (Пн) 22:22

Vovik писал(а):А можно чуть-чуть подробнее, а то я в этих делах как-то несильно шарю.. :roll:

Ты себе не представляешь, сколько народу здесь на форуме, как ты выразился, "несильно шарят" во всем этом...

Cryonyx
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 292
Зарегистрирован: 12.11.2004 (Пт) 15:40
Откуда: Net_SubStream

Сообщение Cryonyx » 11.04.2005 (Пн) 22:26

В том числе и я... :D
А чем отличается идиспатч от втэйбл и с чем их едят? :D
Если тебе не по сердцу мой путь,
Выбери сам или выбери с кем,
А мне по барабану вся эта муть -
Я не червонец, чтобы нравиться всем!
© К.Кинчев
--
Мой блог: щёлкай сюда

FaKk2
El rebelde gurú
El rebelde gurú
Аватара пользователя
 
Сообщения: 2031
Зарегистрирован: 09.03.2003 (Вс) 22:10
Откуда: Los Angeles

Сообщение FaKk2 » 11.04.2005 (Пн) 22:35

Гмм, vtable хранит все доступные методы и интерфейсы,
А IDispatch используется, когда vtable не доступен. Тогда, компилятор опрашивает СОМ сервер насчет каждого метода.
Для получения ответа надо продемонстрировать качества, позволяющие стать компетентным — внимательность, вдумчивость, наблюдательность, желание активно участвовать в выработке решения.

Vi
Постоялец
Постоялец
 
Сообщения: 739
Зарегистрирован: 25.01.2002 (Пт) 11:03
Откуда: Россия, Ижевск

Сообщение Vi » 12.04.2005 (Вт) 6:55

Смотри в MSDN статью "INFO: Late, ID, Early Binding Types Possible in VB for Apps", которая также имеет номер Q138138.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! (с) КВН

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 12.04.2005 (Вт) 9:13

FAKK2 писал(а):Гмм, vtable хранит все доступные методы и интерфейсы,

Не совсем так. VTable хранит все доступные методы одного интерфейса. У каждого интерфейса своя VTable.
FAKK2 писал(а):А IDispatch используется, когда vtable не доступен. Тогда, компилятор опрашивает СОМ сервер насчет каждого метода.

IDispatch используется, когда нужный интерфейс не известен на этапе компиляции, потому что позволяет единообразно обращаться к объекту через любой интерфейс.
Изображение

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 12.04.2005 (Вт) 12:23

Скажем так. Использование двух этих операторов как раз и определяет раннее и позднее связывание:

Код: Выделить всё
Set A=New Object 'раннее
Set A=CreateObject("Object") 'позднее


Зедсь операторы практически равносильны по скорости, если только такая конструкция не стоит у вас в большом цикле(что врядли).

А вот оператором Dim определяется, как будет происходит взаимодейцствие, через vtable или IDispatch.

Код: Выделить всё
Dim A as Excel.Application 'vtable
Dim A as Object 'IDispatch


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

Прояснили ситуацию?

Собственно, приведу пример, когда может использоваться vtable и позднее связывание.

Пример, скорее чисто теоретический, но тем не менее.

Как известно, во всех новых версиях Excel'а сохранилась поддержка старых интерфейсов, и как известно на одном компе могут стоять одновременно, скажем Excel2003 и ExcelXP.

Тогда, такой код, написанный на машине с наиболее старой версией Excel'а(кажем,97) будет делать следующее:
Код: Выделить всё

'Данный код совмещает скорость vtable и гибкость позднего связывания
Dim A as Exel.Application
Select case InputBox("Какую версию excel запустить?")
case "2000"
   Set A=CreateObject("Excel.Application.9")
case "XP"
   Set A=CreateObject("Excel.Application.10")
case "2003"
   Set A=CreateObject("Excel.Application.11")
end select


Как я уже сказал, пример чисто теоретический, но все же.
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 12.04.2005 (Вт) 17:40

ANDLL писал(а):Скажем так. Использование двух этих операторов как раз и определяет раннее и позднее связывание:

Код: Выделить всё
Set A=New Object 'раннее
Set A=CreateObject("Object") 'позднее


Как раз нет. Эти операторы совершенно равнозначны.
Раннее или позднее связывание будет, определяется исключительно типом А.

"Раннее/позднее" и "VTable/Dispatch" - это полностью одно и тоже, а не два разных деления. Примера, "когда может использоваться vtable и позднее связывание" одновременно - быть не может.
Изображение

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 12.04.2005 (Вт) 18:35

Не будем обсуждать терминологию. Но Между New и CreateObject есть одно отличие: New запрашивает у CoCreateObject сразу указатель на требуемый интерфейс, а CreateObject сначала запрашивает IDispatch, а уже потом оператор Set, если надо вызывает QueryInterface. В крайнем случае, мне так кажеться.
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 13.04.2005 (Ср) 3:27

Тебе так кажется.
CreateObject запрашивает тот интерфейс, который соответствует типу переменной. По крайней мере, мне так кажется :)
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 13.04.2005 (Ср) 10:24

Э... GSerg, CreateObject объявлена как Variant, поэтому действительно возвращает IDispatch. А потом Set действительно приводит объект к нужному интерфейсу.
Между New и CreateObject есть более существенное отличие: New создаёт объект по CLSID, а CreateObject - по ProgID. Т.е. CreateObject всегда берёт последнюю версию объекта, а New - ту, которая была на машине у программиста.

Другое дело, что к сабжу все эти отличия не относятся никаким боком.
Изображение

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 13.04.2005 (Ср) 12:38

Чё-то я дизасмил, дизасмил... Ты знаешь, я бы даже не сказал, что CreateObject возвращает Variant... Она вызывает rtcCreateObject2, та возвращает в eax некую цифирь, которая потом передаётся в __vbaObjSetAddRef с целью копирования в локальную переменную... А поскольку __vbaObjSetAddRef работает не с вариантами, то... Хотя кто её знает :)

Но знаешь, функция Int тоже вроде как объявлена как Variant, а возвращает Double :)
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

marvan
Бывалый
Бывалый
 
Сообщения: 269
Зарегистрирован: 22.06.2004 (Вт) 13:26
Откуда: Москва

Сообщение marvan » 13.04.2005 (Ср) 13:30

если я правильно понял, то
Код: Выделить всё
Dim A as Excel.Application 'раннее - vtable
Dim A as Object 'позднее - IDispatch

А эти строки не определяют производительность
Код: Выделить всё
Set A=New Excel.Application
Set A=CreateObject("Excel.Application")
Set A=CreateObject("Excel.Application.10")

но в первом случае будет создаваться (если получится) Application той версии, которая была установлена в References программы до её компилляции. Во втором - быдет использован Excel последней версии из всех установленных на машине. И в третьем попытка создать Application 10 версии.
Правильно ли выше сказанное и как отразится на программе, если использовать
Код: Выделить всё
Dim A as Variant
?

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 13.04.2005 (Ср) 13:43

Очень правильно вышесказанное :)


А это отразится только отрицательно, ибо перед (IDispatch)object->Invoke будет ещё и определение того, а действительно ли там ещё object или уже нет :)
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

AlexVBS
Начинающий
Начинающий
 
Сообщения: 2
Зарегистрирован: 19.04.2005 (Вт) 9:12

Где логика? Где разум?

Сообщение AlexVBS » 19.04.2005 (Вт) 10:22

Подскажите, плз, где засада?

Есть ActiveX библиотека (DLL) созданная на Делфях содержащая СОМ объект. К проекту она подключена (через Project->References...).

Создаю код:

Dim obj As New ShowMsg
Dim Value As String
obj.ShowIt ("Starting...")
Call obj.Test("Indicator", Value)
Form1.Caption = Value

Все замечательно работает. Ок! Пробуем по другому:

Dim obj As ShowMsg
Set obj = New ShowMsg
Dim Value As String
obj.ShowIt ("Starting...")
Call obj.Test("Indicator", Value)
Form1.Caption = Value

Тоже работает. Пытаюсь добиться позднего связывания:

Dim obj
Dim Value As String
Set obj = CreateObject("AXMsg.ShowMsg")
obj.ShowIt ("Starting...") ' <- Run-time Error (424): Object required !!!
Call obj.Test("Indicator", Value)
Form1.Caption = Value

В чем ошибка??? В реестре вся необходимая информация об объекте присутствует. Помогите разобраться!

Заранее благодарен за ответ.

codemaster
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 604
Зарегистрирован: 13.02.2004 (Пт) 13:35

Re: Где логика? Где разум?

Сообщение codemaster » 19.04.2005 (Вт) 10:36

AlexVBS писал(а):Подскажите, плз, где засада?


Создаю код:

Dim obj As New ShowMsg
Dim Value As String
obj.ShowIt ("Starting...")
Call obj.Test("Indicator", Value)
Form1.Caption = Value


Тоже работает. Пытаюсь добиться позднего связывания:

Dim obj
Dim Value As String
Set obj = CreateObject("AXMsg.ShowMsg")
obj.ShowIt ("Starting...") ' <- Run-time Error (424): Object required !!!
Call obj.Test("Indicator", Value)
Form1.Caption = Value

В чем ошибка??? Помогите разобраться!

Заранее благодарен за ответ.



Ошибка в поддержке IDispatch, так как первый вызов идет через vtbl, а второй как раз через IDispatch. Надо проверить, что интерфейс помечен в idl как дуальный ([dual]),

Если на С то класс компонента дожен унаследован от IDispatchImpl<...> и в карте интерфейсов есть вхождение для IDispa

Как это делается на Delphi - х.з. :cry:
//<-
Mit freundlichen Grüßen
//->

AlexVBS
Начинающий
Начинающий
 
Сообщения: 2
Зарегистрирован: 19.04.2005 (Вт) 9:12

Благодарности

Сообщение AlexVBS » 19.04.2005 (Вт) 11:15

Спасибо, codemaster! Действительно дело именно в этом - не обратил на это внимание при создании объекта - ну, бывает шишканул... :lol:


Вернуться в Visual Basic 1–6

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

Сейчас этот форум просматривают: Google-бот, Yandex-бот и гости: 165

    TopList