Как по-человечески вернуть описание ошибки из COM на ATL?
От: fbr  
Дата: 28.07.03 15:38
Оценка:
Пардон за тупой квесчн, просто скока не пробовал и читал МСДН — ничего не получается.
Надо вернуть из COMа свой error description(процедура возвращает не S_OK или S_FALSE) например то что возвращает GetLastError. Как можно это сделать (пробовал определить свой код ошибки и поюзать ATLные ф-ции Error — нифига не выходит, интерфейс подерживает ISupportErrorInfo)?
Re: Как по-человечески вернуть описание ошибки из COM на ATL
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 28.07.03 17:21
Оценка:
Здравствуйте, fbr, Вы писали:

fbr>Пардон за тупой квесчн, просто скока не пробовал и читал МСДН — ничего не получается.

fbr>Надо вернуть из COMа свой error description(процедура возвращает не S_OK или S_FALSE) например то что возвращает GetLastError. Как можно это сделать (пробовал определить свой код ошибки и поюзать ATLные ф-ции Error — нифига не выходит, интерфейс подерживает ISupportErrorInfo)?

в COM-объекте перед выходом из метода:

        Error( "описание ошибки" );
        return E_FAIL;


в программе, которая использует COM-объект:
если обертка для COM-объекта создавалась через
#import "mycom.dll"  no_namespace named_guids

то просто:
try
{
// вызов метода COM-объекта
}
catch ( _com_error & er )
{
  // в  er.Description() лежит "описание ошибки"
}


если через
#import "mycom.dll"  raw_interfaces_only, no_namespace, named_guids

то информацию об ошибке нужно предварительно вытащить
HRESULT hres;
IErrorInfo* pErr = NULL;

try
{
    hres = ....// вызов метода COM-объекта

    if ( FAILED( hres ) )
    {
        GetErrorInfo( NULL, &pErr );
        _com_raise_error( hres, pErr );
    }
}
catch ( _com_error & er )
{
  // в  er.Description() лежит "описание ошибки"
}
Re: Как по-человечески вернуть описание ошибки из COM на ATL
От: promko Украина  
Дата: 28.07.03 21:25
Оценка:
Здравствуйте, fbr, Вы писали:

fbr>Пардон за тупой квесчн, просто скока не пробовал и читал МСДН — ничего не получается.

fbr>Надо вернуть из COMа свой error description(процедура возвращает не S_OK или S_FALSE) например то что возвращает GetLastError. Как можно это сделать (пробовал определить свой код ошибки и поюзать ATLные ф-ции Error — нифига не выходит, интерфейс подерживает ISupportErrorInfo)?

If you want to return Win32 error code(typically obtained from GetLastError())
from one of your methods, convert it to an HRESULT with the HRESULT_FROM_WIN32()
macro. If you receive an HRESULT with a facility code of FACILITY_WIN32, use HRESULT_CODE to extract the Win32 error code

Re: Как по-человечески вернуть описание ошибки из COM на ATL
От: swamp Россия  
Дата: 29.07.03 06:27
Оценка:
Здравствуйте, fbr, Вы писали:

fbr>Пардон за тупой квесчн, просто скока не пробовал и читал МСДН — ничего не получается.

fbr>Надо вернуть из COMа свой error description(процедура возвращает не S_OK или S_FALSE) например то что возвращает GetLastError. Как можно это сделать (пробовал определить свой код ошибки и поюзать ATLные ф-ции Error — нифига не выходит, интерфейс подерживает ISupportErrorInfo)?

Читай SetErrorInfo/GetErrorInfo (именно этим пользуется VB чтобы показывать сообщения об ошибках). Ну или если ты пользуешься ATL, можешь юзать AtlReportError.
... << RSDN@Home 1.1 beta 1 >> (Ramones: All The Way (End Of The Century))
Sincerely yours,
Andrew Simontsev.
Re[2]: Как по-человечески вернуть описание ошибки из COM на
От: fbr  
Дата: 29.07.03 09:18
Оценка:
Здравствуйте, Odi$$ey, Вы писали:

OE>Здравствуйте, fbr, Вы писали:


fbr>>Пардон за тупой квесчн, просто скока не пробовал и читал МСДН — ничего не получается.

fbr>>Надо вернуть из COMа свой error description(процедура возвращает не S_OK или S_FALSE) например то что возвращает GetLastError. Как можно это сделать (пробовал определить свой код ошибки и поюзать ATLные ф-ции Error — нифига не выходит, интерфейс подерживает ISupportErrorInfo)?

OE>в COM-объекте перед выходом из метода:


OE>
OE>        Error( "описание ошибки" );
OE>        return E_FAIL;
OE>


OE>в программе, которая использует COM-объект:

OE>если обертка для COM-объекта создавалась через
OE>
OE>#import "mycom.dll"  no_namespace named_guids
OE>

OE>то просто:
OE>
OE>try
OE>{
OE>// вызов метода COM-объекта
OE>}
OE>catch ( _com_error & er )
OE>{
OE>  // в  er.Description() лежит "описание ошибки"
OE>}
OE>


OE>если через

OE>
OE>#import "mycom.dll"  raw_interfaces_only, no_namespace, named_guids
OE>

OE>то информацию об ошибке нужно предварительно вытащить
OE>
OE>HRESULT hres;
OE>IErrorInfo* pErr = NULL;

OE>try
OE>{
OE>    hres = ....// вызов метода COM-объекта

OE>    if ( FAILED( hres ) )
OE>    {
OE>        GetErrorInfo( NULL, &pErr );
OE>        _com_raise_error( hres, pErr );
OE>    }
OE>}
OE>catch ( _com_error & er )
OE>{
OE>  // в  er.Description() лежит "описание ошибки"
OE>}
OE>


Это все хорошо конечно но следующий кусок кода возвращает "Unspecified error" вместо "Error Raised"
STDMETHODIMP CTestObj::doError(VARIANT vIn)
{
    if (vIn.vt != VT_BSTR)
    {
        Error("Error Raised");
        return E_FAIL;
    }

    return S_OK;
}

VBScript
Set obj = CreateObject("TestCOM.TestObj")

obj.doError(0)

Set obj = Nothing
Re[3]: Как по-человечески вернуть описание ошибки из COM на
От: MaximE Великобритания  
Дата: 29.07.03 09:45
Оценка:
fbr>Это все хорошо конечно но следующий кусок кода возвращает "Unspecified error" вместо "Error Raised"

Твой кокласс должен поддержать ин-с ISupportErrorInfo.
Re[3]: Как по-человечески вернуть описание ошибки из COM на
От: Vi2 Удмуртия http://www.adem.ru
Дата: 29.07.03 09:58
Оценка:
Здравствуйте, fbr, Вы писали:

fbr>Это все хорошо конечно но следующий кусок кода возвращает "Unspecified error" вместо "Error Raised"

fbr>STDMETHODIMP CTestObj::doError(VARIANT vIn)
fbr>{
fbr>    if (vIn.vt != VT_BSTR)
fbr>    {
fbr>        Error("Error Raised");
fbr>        return E_FAIL;
fbr>    }
fbr>    return S_OK;
fbr>}

fbr>VBScript
fbr>Set obj = CreateObject("TestCOM.TestObj")
fbr>obj.doError(0)
fbr>Set obj = Nothing

Скрипты (т.е. те, кто работает с IDispatch::Invoke) реагируют на возврат кода DISP_E_EXCEPTION, который обрабатывается имплементацией IDispatch твоего интерфейса по выходу из твоего метода. По этому коду устанавливаются необходимые параметры Invoke, которые и приведут к коректному получению ошибки.

Т.е. нужно
    if (vIn.vt != VT_BSTR)
    {
        return Error("Error Raised");
    }
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.