Re[2]: IEnumXXXX->Next возвращает........
От: Alex Fedotov США  
Дата: 19.07.04 05:00
Оценка: 10 (1)
Здравствуйте, Vi2, Вы писали:

Vi2>
Vi2>ULONG celtFetchedButNotUsed;
Vi2>hRes=ppenumClsid->Next(1,rgelt,&celtFetchedButNotUsed);
Vi2>

Vi2>Не все прокси любят NULL указатели, но вроде стандартная прокси на такие интерфейсы (IEnumXXXX etc) позволяет ему быть NULL.

Я бы сказал, что возможность передать NULL в IEnumXXX скорее исключение, чем правило. Есть разница, как объявлен метод Next в интерфейсах IEnumGUID (он же IEnumCLSID) и, скажем, IEnumMoniker:

interface IEnumGUID : IUnknown
{
    HRESULT Next(
    [in] ULONG celt,
    [out, size_is(celt), length_is(*pceltFetched)] GUID *rgelt,
    [out] ULONG *pceltFetched);

    ...
};

interface IEnumMoniker : IUnknown
{

    [local]
    HRESULT Next(
        [in] ULONG celt,
        [out, size_is(celt), length_is(*pceltFetched)]
        IMoniker **rgelt,
        [out] ULONG *pceltFetched);

    [call_as(Next)]
    HRESULT RemoteNext(
        [in] ULONG celt,
        [out, size_is(celt), length_is(*pceltFetched)]
        IMoniker **rgelt,
        [out] ULONG *pceltFetched);
  
     ...
};


Стандартная proxy, которая геренируется MIDL, никогда не позволяет [ref]-параметру быть NULL. Чтобы можно было передать NULL, параметр должен быть [unique] или [ptr].

С другой стороны, видно, что в случае IEnumMoniker локальные и удаленные вызовы обрабатываются раздельно (насколько я понимаю, в основном из соображений производительности — локальная прокси вызывает RemoteNext c большими кусками, даже если клиент выбирает по одному элементу). Возможно, что эта прокси и позволяет передавать NULL.

Насколько я понял быстрым поиском "IEnum" по *.idl, такая оптимизация применяется только для "core" интерфейсов (IEnumUnknown, IEnumVARIANT, IEnumMoniker, может еще какие), а большинство самодельных типа IEnumClusCfgManagedResources не заморачиваются этим и пользуются MIDL-generated proxy.
-- Alex Fedotov
Re: IEnumXXXX->Next возвращает........
От: Vi2 Удмуртия http://www.adem.ru
Дата: 19.07.04 04:33
Оценка: 1 (1)
Здравствуйте, Sensor771, Вы писали:

S>GUID rgelt[1];    
S>//ppenumClsid-указатель на IEnumGUID
S>hRes=ppenumClsid->Reset(); //тут в hRes - S_OK        
S>hRes=ppenumClsid->Next(1,rgelt,NULL);
S>//тут в hRes длиннющий код ошибки который ErrorLookup объясняет как - "Заглушке передан нулевой указатель ссылки"

S>Ткните пожалуйста в какой стороне искать гвоздь.

ULONG celtFetchedButNotUsed;
hRes=ppenumClsid->Next(1,rgelt,&celtFetchedButNotUsed);

Не все прокси любят NULL указатели, но вроде стандартная прокси на такие интерфейсы (IEnumXXXX etc) позволяет ему быть NULL. Но если тебе не нужно значение, которое возвращается, просто не используй его, но передай этой дотошной прокси.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
IEnumXXXX->Next возвращает........
От: Sensor771  
Дата: 17.07.04 08:08
Оценка:
Объясните несмышленышу.....
Есть такой код:

GUID rgelt[1];
//ppenumClsid-указатель на IEnumGUID
hRes=ppenumClsid->Reset();
//тут в hRes — S_OK
hRes=ppenumClsid->Next(1,rgelt,NULL);
//тут в hRes длиннющий код ошибки который ErrorLookup объясняет как — "Заглушке передан нулевой указатель ссылки"

Ткните пожалуйста в какой стороне искать гвоздь.
Заранее спасибо.
Re: IEnumXXXX->Next возвращает........
От: Нахлобуч Великобритания https://hglabhq.com
Дата: 18.07.04 18:52
Оценка:
Здравствуйте, Sensor771, Вы писали:

S>Объясните несмышленышу.....

S>Есть такой код:

S>GUID rgelt[1];    
S>//ppenumClsid-указатель на IEnumGUID
S>hRes=ppenumClsid->Reset();
S>//тут в hRes - S_OK        
S>hRes=ppenumClsid->Next(1,rgelt,NULL);
S>//тут в hRes длиннющий код ошибки который ErrorLookup объясняет как - "Заглушке передан нулевой указатель ссылки"


S>Ткните пожалуйста в какой стороне искать гвоздь.

S>Заранее спасибо.

А так:

GUID rgelt[1];
hRes = ppenumClsid->Reset();
hRes = ppenumClsid->Next(1, &rgelt, NULL);
... << Rsdn@Home 1.1.4 beta 1 >>
HgLab: Mercurial Server and Repository Management for Windows
Re[3]: IEnumXXXX->Next возвращает........
От: LaFlour Австралия blog: http://spaces.live.com/laflour
Дата: 20.07.04 04:05
Оценка:
Здравствуйте, Alex Fedotov, Вы писали:



AF>Я бы сказал, что возможность передать NULL в IEnumXXX скорее исключение, чем правило. Есть разница, как объявлен метод Next в интерфейсах IEnumGUID (он же IEnumCLSID) и, скажем, IEnumMoniker:


Но это идет только в аспекте IEnumXXX, т.к. корни идут к определению вызовов Next до того как ввели IDL определение.

AF>Стандартная proxy, которая геренируется MIDL, никогда не позволяет [ref]-параметру быть NULL. Чтобы можно было передать NULL, параметр должен быть [unique] или [ptr].


да, но тут получаем IDL противоречие с нашим определением Next, так как негде хранить результат.

AF>С другой стороны, видно, что в случае IEnumMoniker локальные и удаленные вызовы обрабатываются раздельно (насколько я понимаю, в основном из соображений производительности — локальная прокси вызывает RemoteNext c большими кусками, даже если клиент выбирает по одному элементу). Возможно, что эта прокси и позволяет передавать NULL.


И вот как раз именно для того чтобы избавиться от этого противоречия было введено разделение на вызываемую
форму и отправляемую форму.
... << Rsdn@Home 1.1.4 beta 1 >>
Re[4]: IEnumXXXX->Next возвращает........
От: Alex Fedotov США  
Дата: 20.07.04 06:35
Оценка:
Здравствуйте, LaFlour, Вы писали:

LF>Здравствуйте, Alex Fedotov, Вы писали:




AF>>Я бы сказал, что возможность передать NULL в IEnumXXX скорее исключение, чем правило. Есть разница, как объявлен метод Next в интерфейсах IEnumGUID (он же IEnumCLSID) и, скажем, IEnumMoniker:


LF>Но это идет только в аспекте IEnumXXX, т.к. корни идут к определению вызовов Next до того как ввели IDL определение.


Мысль не понял. Если в до-IDL времена параметр pceltFetched мог указываться как NULL, то на языке IDL это выражается как

    [in,out,unique] ULONG * pceltFetched



AF>>Стандартная proxy, которая геренируется MIDL, никогда не позволяет [ref]-параметру быть NULL. Чтобы можно было передать NULL, параметр должен быть [unique] или [ptr].


LF>да, но тут получаем IDL противоречие с нашим определением Next, так как негде хранить результат.


Опять не понял.

AF>>С другой стороны, видно, что в случае IEnumMoniker локальные и удаленные вызовы обрабатываются раздельно (насколько я понимаю, в основном из соображений производительности — локальная прокси вызывает RemoteNext c большими кусками, даже если клиент выбирает по одному элементу). Возможно, что эта прокси и позволяет передавать NULL.


LF>И вот как раз именно для того чтобы избавиться от этого противоречия было введено разделение на вызываемую

LF>форму и отправляемую форму.

И опять не понял.
-- Alex Fedotov
Re[5]: IEnumXXXX->Next возвращает........
От: LaFlour Австралия blog: http://spaces.live.com/laflour
Дата: 20.07.04 07:25
Оценка:
Здравствуйте, Alex Fedotov, Вы писали:

AF>>>Я бы сказал, что возможность передать NULL в IEnumXXX скорее исключение, чем правило. Есть разница, как объявлен метод Next в интерфейсах IEnumGUID (он же IEnumCLSID) и, скажем, IEnumMoniker:

LF>>Но это идет только в аспекте IEnumXXX, т.к. корни идут к определению вызовов Next до того как ввели IDL определение.
AF>Мысль не понял. Если в до-IDL времена параметр pceltFetched мог указываться как NULL, то на языке IDL это выражается как

AF>
AF>    [in,out,unique] ULONG * pceltFetched
AF>


Это из области aliasing techniques
Цитирую Бокса


Идиома нумератора СОМ была разработана раньше, чем компилятор IDL, поддерживаемый СОМ. Это означает, что первый разработчик интерфейса IEnum не мог проверить свою разработку на соответствие известным правилам преобразования в IDL. Метод перечислителя Next не может быть чисто преобразован в IDL1. Рассмотрим идеальный IDL-прототип метода Next:

HRESULT Next([in] ULONG cElems,
[out, size_is(cElems), length_is(*pcFetched)] double *prg,
[out] ULONG *pcFetched);

К сожалению, исходное "до-IDL-овское" определение метода Next устанавливало, что вызывающие программы могут передавать в качестве третьего параметра нулевой указатель, при условии, что первый параметр показывал, что запрашивается только один элемент. Это предоставляло вызывающим программам удобную возможность извлекать по одному элементу за раз:

double dblElem;
hr = p->Next(1, &dblElem, 0);

Данное допустимое использование интерфейса противоречит приведенному выше IDL-определению, так как [out]-параметры самого верхнего уровня не имеют права быть нулевыми (нет места, куда интерфейсный заместитель мог бы сохранять результат). Для разрешения этого противоречия каждое определение метода Next должно использовать атрибут [call_as] для замены вызываемой формы (callable form) метода его отправляемой формой (remotable form).

 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.