Interface IDispatch::Invoke
От: Shaman Marakame США http://www.buydrm.com
Дата: 19.12.05 18:27
Оценка:
Добрый День,

У меня есть такая проблема с Итерфэйсом IDispatch->Invoke

hr = pDisp->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &dispparamsArgs, NULL, &excepinfo, NULL);

Объявляю параметр такими Образом вот примеры:

//DISPPARAMS dispparamsArgs = {(VARIANTARG*)&pbstrXMLDoc, NULL, 1, 0};
DISPPARAMS dispparamsArgs = {NULL, NULL, 0, 0};

Это сам метод каторый мне нужно вызвать:
IRMGetLicense::GetSystemInfo

HRESULT GetSystemInfo(
BSTR* pbstrXMLDoc
);

Параметр "pbstrXMLDoc" [out] укозатель на строку с "system information."

возр. Результат S_OK что означает успешное завершение работы метода.

Но все происходит иначе.
hr = 0x80020009 Exception occurred.
excepinfo = bstrDescription: 0x00176d24 "The parameter is incorrect.

Есть ли сооьражения у кого нибудь по этому поводу ? Если да то помогите плеазе.

Если нужен листинг кода дайте знать

Зарание Спасибо!!!

--
Shaman Marakame.
--
Best regards,
Andrew S. Popov
Re: Interface IDispatch::Invoke
От: Vi2 Удмуртия http://www.adem.ru
Дата: 20.12.05 06:58
Оценка:
Здравствуйте, Shaman Marakame, Вы писали:

SM>У меня есть такая проблема с Итерфэйсом IDispatch->Invoke

  1. Если вызываемый метод описан так
    HRESULT GetSystemInfo([out,retval]BSTR*  pbstrXMLDoc);

    то вызывающий код должен быть
    VARIANT vResult; VariantInit(&vResult);
    DISPPARAMS dispparamsArgs = {NULL, NULL, 0, 0};
    hr = pDisp->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &dispparamsArgs, &vResult, &excepinfo, NULL);

  2. Если вызываемый метод описан так
    HRESULT GetSystemInfo([in,out]BSTR*  pbstrXMLDoc); // или [out]

    то вызывающий код должен быть
    BSTR szInfo = NULL;
    VARIANT vArg0; vArg0.vt=VT_BYREF|VT_BSTR; vArg0.pbstrVal=&szInfo;
    //или же: VARIANT vInfo; vInfo.vt=VT_BSTR; vInfo.bstrVal=NULL;
    //или же: VARIANT vArg0; vArg0.vt=VT_BYREF|VT_VARIANT; vArg0.pvarVal=&vInfo;
    DISPPARAMS dispparamsArgs = {&vArg0, NULL, 1, 0};
    hr = pDisp->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &dispparamsArgs, NULL, &excepinfo, NULL);
Естественно, с освобождением полученной строки или варианта.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re: Interface IDispatch::Invoke
От: Left2 Украина  
Дата: 20.12.05 10:29
Оценка:
на правах совета — посмотри в сторону ATL, он позволяет сильно уменьшит головную боль от работы с IDispatch при помощи CComPtr<IDispatch>.
Re[2]: Interface IDispatch::Invoke
От: Shaman Marakame США http://www.buydrm.com
Дата: 20.12.05 21:20
Оценка:
Здравствуйте, Vi2,

Это то как гласит MSDN:

Syntax:

HRESULT GetSystemInfo(
BSTR* pbstrXMLDoc
);

Parameters:

pbstrXMLDoc

[out] Pointer to a string identifying the system information.

Тоесть я использовал пример №1. и получил тот же Error
hr = 0x80020009 Exception occurred.
excepinfo = bstrDescription: 0x00176d24 "The parameter is incorrect.


Но я решил проверить пример №2 и два случая

в первом варианте
BSTR szInfo = NULL;
VARIANT vArg0; vArg0.vt=VT_BYREF|VT_BSTR; vArg0.pbstrVal=&szInfo;

я получаю ошибку
hr = 0x8002000e Invalid number of parameters.

во втором варианте
VARIANT vInfo; vInfo.vt=VT_BSTR; vInfo.bstrVal=NULL;
VARIANT vArg0; vArg0.vt=VT_BYREF|VT_VARIANT; vArg0.pvarVal=&vInfo;

я получаю ошибку
hr = 0x8002000e Invalid number of parameters.

--
Best regards,
Andrew S. Popov
Re[2]: Interface IDispatch::Invoke
От: Shaman Marakame США http://www.buydrm.com
Дата: 20.12.05 21:21
Оценка:
Здравствуйте, Left2,

У Вас нету ссылок на ету тему ?
--
Best regards,
Andrew S. Popov
Re[3]: Interface IDispatch::Invoke
От: Vi2 Удмуртия http://www.adem.ru
Дата: 21.12.05 04:38
Оценка:
Здравствуйте, Shaman Marakame, Вы писали:

SM>Это то как гласит MSDN:


Раз он упоминается в MSDN, то тогда другое дело!

SM>Syntax:

SM>HRESULT GetSystemInfo( BSTR* pbstrXMLDoc);
SM>Parameters:
SM>pbstrXMLDoc
SM>[out] Pointer to a string identifying the system information.

А теперь находим эту DLL и смотрим OLE Viewer-ом:
    [id(0x60020001), helpstring("method GetSystemInfo")]
    HRESULT GetSystemInfo([out, retval] BSTR* pbstrXMLDoc);

И что мы видим? Пример №1 в чистом виде.

SM>Тоесть я использовал пример №1. и получил тот же Error

SM>hr = 0x80020009 Exception occurred.
SM>excepinfo = bstrDescription: 0x00176d24 "The parameter is incorrect.

Попробуй явно указать тип хранения в Варианте. Это не совсем правильно — все-таки параметр чистый [out], — но может сработать.
VARIANT vResult; /*VariantInit(&vResult);*/ vResult.vt=VT_BSTR; vResult.bstrVal=NULL;
DISPPARAMS dispparamsArgs = {NULL, NULL, 0, 0};
hr = pDisp->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &dispparamsArgs, &vResult, &excepinfo, NULL);


SM>Но я решил проверить пример №2 и два случая

SM>в первом варианте
SM>BSTR szInfo = NULL;
SM>VARIANT vArg0; vArg0.vt=VT_BYREF|VT_BSTR; vArg0.pbstrVal=&szInfo;
SM>я получаю ошибку
SM>hr = 0x8002000e Invalid number of parameters.

SM>во втором варианте

SM>VARIANT vInfo; vInfo.vt=VT_BSTR; vInfo.bstrVal=NULL;
SM>VARIANT vArg0; vArg0.vt=VT_BYREF|VT_VARIANT; vArg0.pvarVal=&vInfo;
SM>я получаю ошибку
SM>hr = 0x8002000e Invalid number of parameters.

Это означает, что метод не принимает дополнительные аргументы.

PS
А зачем этот дуальный интерфейс использовать на С++ явно в ущербном виде?! Не проще ли использовать его vtable и вызывать напрямую:
CComQIPtr<IRMGetLicense> pRMGetLicense(pDisp); // pDisp -> QueryInterface( __uuidof(IRMGetLicense), (void**) &pRMGetLicense) etc
BSTR szInfo = NULL;
hr = pRMGetLicense -> GetSystemInfo( & szInfo );
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[3]: Interface IDispatch::Invoke
От: Left2 Украина  
Дата: 21.12.05 09:32
Оценка:
SM>У Вас нету ссылок на ету тему ?

зачем же меня и на Вы тут на Вы только в качестве перехода на личности обращаются

а зачем ссылки?
открываешь сорцы ATL и читаешь шаблон CComPtr и его специализацию для IDispatch — там всё понятно, за 15 минут можно разобраться
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.