В VB приходит почему-то Nothing вместо корректного значения value. Объекты attr, value и t создаются корректно, до этого вызова я с ними успешно работаю. А вот после вызова получаю в t следующий код ошибки: Object variable or With block variable not set --- происходит исключительная ситуация в коде на VB в момент первого обращения к переменной Value.
Кто-нибудь может что-нибудь посоветовать ? Как правильно передать указатель на интерфейс ?
Программист — это не тот, кто пишет программы, а тот, чьи программы работают.
Re: Передача указателя на интерфейс в COM-объект на VB 6.0
Я че-то не понял. Указатель на объект у тебя val, передаешь ты &value. Если параметр в методе как указано выше, то передавать нужно val.
tks>Кто-нибудь может что-нибудь посоветовать ? Как правильно передать указатель на интерфейс ?
Это не проблема. ТщательнЕе надо.
GS
Re[2]: Передача указателя на интерфейс в COM-объект на VB 6.
Но остался вопрос: зачем эти мистические действия ?
GS>1. Покажи, какой idl (ну, или tlb) создается. Скорее всего, это IValue *Value, но неплохо проверить (открыв dll OleView).
tks>Но остался вопрос: зачем эти мистические действия ?
А что полечилось-то?
Объяснение:
1. AdapterEIS::_IValuePtr value; // это доблестный _com_ptr_t
И когда ты передавал attr->SetItemValue(&value, здесь вызывался код из вот такого оператора _com_ptr_t, где Interface==_IValue:
Как видишь, возвращается указатель на указтель объекта, т.е. _IValue**, но указатель на объект 1) равен NULL, а 2) разрушен через Release. Ты эту ситуацию разрулил, введя дополнительный указатель vl, который не обнуляется при взятии адреса.
2. А счетчик ссылок зачем увеличивать? А уменьшать кто будет? VB? Не дождешься!
3.И вообще зачем передавать этот параметр как ByRef? Достаточно было ByVal и без проблем в коде.
Здравствуйте George Seryakov
GS> Скорее всего, приведение типа. Какой тип у value?
AdapterEIS::_IValuePtr
Видимо оператор & переопределен в _COM_SMARTPTR_TYPEDEF так, что он релизит старый указатель на интерфейс перед возвращением ссылки на него, чтобы можно было спокойно присваивать туда новое значение. Иначе как бы тогда не текла память при вызове:
Здравствуйте Vi2, Вы писали:
Vi2>Здравствуйте tks, Вы писали:
[]
Vi2>3.И вообще зачем передавать этот параметр как ByRef? Достаточно было ByVal и без проблем в коде.
Действительно, указатель на указатель на интерфейс передают, когда хотят, чтобы вызываемая сторона (сервер) создала объект и вернула интерфейс (можно просто вернула интерфейс без создания). При этом по переданному адресу записывается указатель на интерфейс.
У тебя ситуация противоположенная. Клиент должен передать указатель на интерфейс, чтобы сервер просто его использовал. Нет никакой необходимости передавать IInterface**. Если ты думал, что передается IInterface*, то глубоко заблуждался!
СмартПоинтеры всякие — это посуществу указатель на интерфейс. Т.е. практически все они работают по одному принципу. Я имел счастье работать с четырьмя: _com_ptr_t, CComPtr, TComInterface из BCB и еще один из книжки Робинсона. Все они имели только один член — указатель на интерфейс. Все они имели operator->() в котором возвращали этот указатель. Вообщем, вели себя как УКАЗАТЕЛЬ на интерфейс. Соответственно, чисто логически, его адрес будет указателем на указатель на интерфейс. Если ты хочешь получить просто указатель на интерфейс и работаешь с _com_ptr_t, то у него есть оператор: