4 bity zarezerwowane dla przyszłych zastosowań 11 bitów określających źródło błędu 16 bitów określających rodzaj błędu.



Podobne dokumenty
Zdarzenia (events, connection points)

Droga do DCOM DCOM (1996) Windows clipboard (1987) OLE 1 DDE (1992) OLE 2 (1993) COM (1995) Distributed computing (1980s)

Henryk Budzisz. materiały przygotowane w ramach projektu ZPORR nr POKL /08-00

Agregacja. Wykorzystanie innego komponentu bez użycia agregacji. Simple calculator. Extended calculator

//////////////////////////////////////////////////////////// // Kalkulator (prosty) - wersja agregowalna import "unknwn.idl";

Obiekty w plikach wykonywalnych, marshaling

Structured storage, Monikers, Running Object Table

Typy złożone. Struktury, pola bitowe i unie. Programowanie Proceduralne 1

Microsoft Interface Definition Language

Interfejs IUnknown. Każdy obiekt COM musi implementować interfejs IUnknown, który zawiera trzy metody:

Zdalne wywołania procedur. Jarosław Kuchta Programowanie Współbieżne

Dokumentacja techniczna API systemu SimPay.pl

Operatory cd. Relacyjne: ==!= < > <= >= bool b; int i =10, j =20; dzielenie całkowitych wynik jest całkowity! Łączenie tekstu: + string s = "Ala ma ";

Programowanie Komputerów

Kurs programowania. Wykład 1. Wojciech Macyna. 3 marca 2016

METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02

Testy jednostkowe - zastosowanie oprogramowania JUNIT 4.0 Zofia Kruczkiewicz

Inżynieria Wytwarzania Systemów Wbudowanych

Programowanie obiektowe

PHP może zostać rozszerzony o mechanizmy dostępu do różnych baz danych:

1. Wartość, jaką odczytuje się z obszaru przydzielonego obiektowi to: a) I - wartość b) definicja obiektu c) typ oboektu d) p - wartość

Zarządzanie pamięcią

Kompilator języka C na procesor 8051 RC51 implementacja

Dokumentacja smsapi wersja 1.4

MATERIAŁY DO ZAJĘĆ II

Programowanie współbieżne i rozproszone

Dariusz Brzeziński. Politechnika Poznańska, Instytut Informatyki

Języki i metodyka programowania. Typy, operatory, wyrażenia. Wejście i wyjście.

Wprowadzenie do szablonów klas

Wyjątki. Wyjątki. Bogdan Kreczmer. Katedra Cybernetyki i Robotyki Politechnika Wrocławska

C++ język nie dla ludzi o słabych nerwach. Małgorzata Bieńkowska

Procedury składowane. Funkcje vs. procedury Funkcja. Procedura. zazwyczaj ma parametry tylko typu IN; można wywoływać z poziomu

Funkcje przeciążone, konstruktory kopiujące, argumenty domyślne

Pomoc dla użytkowników systemu asix 6 i 7. Drajwer Bufor. Dok. Nr PLP6021 Wersja:

Visual Basic Debugging and Error Handling

Smarty PHP. Leksykon kieszonkowy

Wyjątki (exceptions)

PMiK Programowanie Mikrokontrolera 8051

Wykład 2 Wybrane konstrukcje obiektowych języków programowania (1)

Wyświetlacz alfanumeryczny LCD zbudowany na sterowniku HD44780

API transakcyjne BitMarket.pl

Języki i metodyka programowania. Język C# pętle, sterowanie, wyjątki

SMS Kod Automatyczny

Programowanie w językach

Sun RPC/XDR 10. listopada Dariusz Wawrzyniak (IIPP) 1

Algorytmy i struktury danych. wykład 1

Język ludzki kod maszynowy

Java: kilka brakujących szczegółów i uniwersalna nadklasa Object

JAVA W SUPER EXPRESOWEJ PIGUŁCE

Kurs programowania. Wykład 3. Wojciech Macyna. 22 marca 2019

Zadanie 04 Ktory z ponizszych typow danych w jezyku ANSI C jest typem zmiennoprzecinkowym pojedynczej precyzji?

Pobieranie argumentów wiersza polecenia

Automatyczne tworzenie operatora = Integer2& operator=(const Integer& prawy) { zdefiniuje. Integer::operator=(ri);

Zofia Kruczkiewicz, Programowanie obiektowe - java, wykład 2 1

Wykład 15. Literatura. Kompilatory. Elementarne różnice. Preprocesor. Słowa kluczowe

Wykład VII. Programowanie. dr inż. Janusz Słupik. Gliwice, Wydział Matematyki Stosowanej Politechniki Śląskiej. c Copyright 2014 Janusz Słupik

2018 Marcin Kukliński. Niesforne bity i bajty

Wstęp do wiadomości teoretycznych (nie, nie jest to masło maślane ani wstęp, wstępów proszę cierpliwie czytać)

Sun RPC/XDR. Dariusz Wawrzyniak 1

Programowanie RAD Delphi

Wykład I. Programowanie II - semestr II Kierunek Informatyka. dr inż. Janusz Słupik. Wydział Matematyki Stosowanej Politechniki Śląskiej

Identyfikacje typu na etapie. wykonania (RTTI)

Swift (pol. jerzyk) nowy język programowania zaprezentowany latem 2014 r. (prace od 2010 r.)

Rodzina protokołów TCP/IP. Aplikacja: ipconfig.

external Data Representation

public: // interfejs private: // implementacja // składowe klasy protected: // póki nie będziemy dziedziczyć, // to pole nas nie interesuje

Podstawy programowania skrót z wykładów:

external Data Representation

Obsługa wyjątków. Język C++ WW12

Kurs programowania. Wykład 13. Wojciech Macyna. 14 czerwiec 2017

Programowanie w języku Java - Wyjątki, obsługa wyjątków, generowanie wyjątków

Laboratorium Komputerowe Systemy Pomiarowe

Komunikacja między sterownikami przez protokół ADS

Platformy Programistyczne Podstawy języka Java

Specyfikacja testów akceptacyjnych Radosław Iglantowicz, Tomasz Bruździński,

Wykład 4 Delegat (delegate), właściwości indeksowane, zdarzenie (event) Zofia Kruczkiewicz

RPC. Zdalne wywoływanie procedur (ang. Remote Procedure Calls )

Technologie COM i ActiveX COM - Component Object Model

Java Język programowania

Microsoft Foundation Classes

Wykład 8: Obsługa Wyjątków

Programowanie współbieżne. Tworzenie i obsługa semaforów oraz wątków przy użyciu funkcji Windows API.

Co nie powinno być umieszczane w plikach nagłówkowych:

Scenariusz Web Design DHTML na 10 sesji. - Strony statyczne I dynamiczne. - Dodawanie kodu VBScript do strony HTML. Rysunek nie jest potrzebny

Kurs programowania. Wykład 9. Wojciech Macyna. 28 kwiecień 2016

InsERT GT Własne COM 1.0

Uwaga Przed każdą aktualizacją, zalecane jest zrobienie kopii bezpieczeństwa bazy oraz bibliotek programu

Obsługa błędów w SQL i transakcje. Obsługa błędów w SQL

TEMAT : KLASY DZIEDZICZENIE

Programowanie obiektowe

Programowanie. Sylwester Arabas. prowadzący ćwiczenia: Magdalena Kuich, Krzysztof Piasecki, Łukasz Dulny. Wydział Fizyki Uniwersytetu Warszawskiego

Wdrożenie modułu płatności eservice. dla systemu oscommerce 2.3.x

Wywoływanie metod zdalnych

PROE wykład 2 operacje na wskaźnikach. dr inż. Jacek Naruniec

Podstawy programowania. Wykład Co jeszcze... Przypomnienia, uzupełnienia. Krzysztof Banaś Podstawy programowania 1

ezwroty WebApi Dokumentacja techniczna

Programowanie I C / C++ laboratorium 03 arytmetyka, operatory

UML a kod w C++ i Javie. Przypadki użycia. Diagramy klas. Klasy użytkowników i wykorzystywane funkcje. Związki pomiędzy przypadkami.

// LISTING #2 DRUGIE PODEJŚCIE

Dr inż. Grażyna KRUPIŃSKA. D-10 pokój 227 WYKŁAD 7 WSTĘP DO INFORMATYKI

Transkrypt:

Zgłaszanie błędów

HRESULT Każda metoda interfejsu COM zwraca informację o błędzie w postaci typu HRESULT (long int). Struktura reprezentacji bitowej HRESULT podzielona jest na 4 sekcje: 1 bit błędu 4 bity zarezerwowane dla przyszłych zastosowań 11 bitów określających źródło błędu 16 bitów określających rodzaj błędu Zarezerwowane 0 0 0 0 Bit błędu Źródło błędu Kod błędu

HRESULT Bit błędu Bit błędu informuje czy zwrócony kod sygnalizuje błędnie wykonaną operację, czy jedynie jej zwraca status: SEVERITY_SUCCESS (0) operacja powiodła się SEVERITY_ERROR (1) operacja zakończyła się błędem Do sprawdzenia wartości bitu błędu służy para makrodefinicji SUCCEEDED(hr) i FAILED(hr). Zwracają one wartość TRUE odpowiednio dla operacji zakończonej pomyślnie i operacji zakończonej błędem. Istnieje też makrodefinicja HRESULT_SEVERITY(hr), która zwraca wartość bitu błędu.

HRESULT Źródło błędu FACILITY_WINDOWS (8) inne błędy pochodzące od systemu Pole źródła błędu definiuje, jaka usługa wywołała błąd. Zdefiniowane są obecnie następujące źródła błędów związane z COM: FACILITY_DISPATCH (2) błędy wywołane w metodach interfejsu IDispatch FACILITY_ITF (4) błędy w innych metodach interfejsu FACILITY_NULL (0) niezdefiniowane źródło błędu FACILITY_RPC (1) błędy związane z RPC FACILITY_STORAGE (3) błędy związane z metodami IStorage i IStream FACILITY_WIN32 (7) błędy zwracane przez funkcje systemowe Win32 Windows Wartość pola źródła błędu można odczytać za pomocą makrodefinicji HRESULT_FACILITY(hr).

HRESULT Kod błędu Kody błędów definiowane są niezależnie dla różnych źródeł błędów. Zakres kodów 0x0000 0x01FF zarezerwowany jest dla standardowych błędów operacji. Pozostały zakres 0x0200 0xFFFF może zostać wykorzystany do niestandardowych innych komunikatów. Wartość kodu błędu można odczytać makrodefinicją HRESULT_CODE(hr). Do konwersji błędów systemowych odczytywanych funkcją GetLastError() do postaci HRESULT służy makrodefinicja HRESULT_FROM_WIN32(err). Własny kod błędu można utworzyć za pomocą makrodefinicji MAKE_HRESULT(sev,fac,code), gdzie: sev = SEVERITY_SUCCESS lub SEVERITY_ERROR fac = FACILITY_ITF code = wartość z zakresu 0x0200 0xFFFF

HRESULT HRESULT Value Description E_ABORT 0x80004004 The operation was aborted because of an unspecified error. E_ACCESSDENIED 0x80070005 A general access-denied error. E_FAIL 0x80004005 An unspecified failure has occurred. E_HANDLE 0x80070006 An invalid handle was used. E_INVALIDARG 0x80070057 One or more arguments are invalid. E_NOINTERFACE 0x80004002 The QueryInterface method did not recognize the requested interface. The interface is not supported. E_NOTIMPL 0x80004001 The method is not implemented. E_OUTOFMEMORY 0x8007000E The method failed to allocate necessary memory. E_PENDING 0x8000000A The data necessary to complete the operation is not yet available. E_POINTER 0x80004003 An invalid pointer was used. E_UNEXPECTED 0x8000FFFF A catastrophic failure has occurred. S_FALSE 0x00000001 The method succeeded and returned the boolean value FALSE. S_OK 0x00000000 The method succeeded. If a boolean return value is expected, the returned value is TRUE.

HRESULT Często stosowanym rozwiązaniem stosowanym do identyfikacji błędów są stałe wyliczeniowe: #include <winerror.h> #define MAKE_HRESULT_ERROR(nCode) \ MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, ncode) typedef [uuid(39fb3ab1-de17-4a10-a3db-95236c055135), helpstring("possible error return codes")] enum [helpstring("the hardware does not support the high perf. counters.")] tmerrorhighperftimernotsupported = MAKE_HRESULT_ERROR(0x0200), [helpstring("start needs to be called before ElapsedTime.")] tmerrorstartnotcalled = MAKE_HRESULT_ERROR(0x0201), TmStopwatchError; library TIMERSLib... enum TMStopwatchError;...

W celu umożliwienia klientowi odczytu rozszerzonej informacji o błędzie opracowano standardowe interfejsy ISupportErrorInfo i IErrorInfo. ISupportErrorInfo zawiera tylko jedną metodę InterfaceSupportErrorInfo() informującą czy dla określonego interfejsu dostępna jest rozszerzona informacja o błędzie. interface ISupportErrorInfo: IUnknown HRESULT InterfaceSupportsErrorInfo( [in] REFIID riid );

ISupportErrorInfo //Custom example HRESULT CStopwatch::InterfaceSupportsErrorInfo(REFIID riid) if (riid == IID_IStopwatch) return S_OK; else return S_FALSE; //ATL generated form STDMETHODIMP CStopwatch::InterfaceSupportsErrorInfo(REFIID riid) static const IID* arr[] = &IID_IStopwatch, &IID_IStopwatch2, ; for (int i=0; i < sizeof(arr) / sizeof(arr[0]); i++) if (InlineIsEqualGUID(*arr[i],riid)) return S_OK; return S_FALSE;

ICreateErrorInfo Komponent, gdy podczas wykonywania procedury wystąpił błąd, powinien utworzyć obiekt ICreateErrorInfo za pomocą funkcji CreateErrorInfo(): ICreateErrorInfo* pcreateerrorinfo; CreateErrorInfo(&pCreateErrorInfo); Obiekt ICreateErrorInfo zawiera zestaw metod pozwalających na ustawienie rozszerzonej informacji o błędzie: interface ICreateErrorInfo: IUnknown HRESULT SetGUID( [in] REFGUID rguid ); HRESULT SetSource( [in] LPOLESTR szsource ); HRESULT SetDescription( [in] LPOLESTR szdescription ); HRESULT SetHelpFile( [in] LPOLESTR szhelpfile ); HRESULT SetHelpContext( [in] DWORD dwhelpcontext );

ICreateErrorInfo SetDescription() definiuje opis zaistniałego błędu SetSource() identyfikuje komponent, w którym wystąpił błąd SetGUID() identyfikuje interfejs, dla którego wystąpił błąd. SetHelpContext() definiuje identyfikator opisu błędu w pliku pomocy. SetHelpFile() definiuje lokalizację i nazwę pliku pomocy.

ICreateErrorInfo Dla utworzonego obiektu ICreateErrorInfo należy wywołać metody Set...() i podać informacje dotyczące błędu. Następnie z tego obiektu należy pobrać interfejs IErrorInfo i ustawić bierzącą informację o błędzie funkcją SetErrorInfo(). HRESULT CStopwatch::Start() if ( QueryPerformanceCounter((LARGE_INTEGER*) &m_nstarttime) ) return S_OK; else ICreateErrorInfo* pcreateerrorinfo; IErrorInfo* perrorinfo; CreateErrorInfo(&pCreateErrorInfo); pcreateerrorinfo->setdescription("high perf. counters not supported"); pcreateerrorinfo->setguid(iid_istopwatch); pcreateerrorinfo->setsource(l"component.stopwatch"); pcreateerrorinfo->queryinterface(iid_ierrorinfo,(void**)&perrorinfo); SetErrorInfo(0, perrorinfo); perrorinfo->release(); pcreateerrorinfo->release(); return tmerrorhighperformancetimersnotsupported;

Error() W celu uproszczenia procedury tworzenia opisu błędu klasa ATL CComCoClass będąca klasą bazową komponentów ATL COM, posiada zestaw funkcji Error(), które są odpowiedzialne za procedurę ustawiania informacji o błędzie: HRESULT Error( LPCOLESTR lpszdesc, const IID& iid, HRESULT hres ); HRESULT Error( LPCOLESTR lpszdesc, DWORD dwhelpid, LPCOLESTR lpszhelpfile, const IID& iid, HRESULT hres ); HRESULT Error( LPCSTR lpszdesc, const IID& iid, HRESULT hres ); HRESULT Error( LPCSTR lpszdesc, DWORD dwhelpid, LPCSTR lpszhelpfile, const IID& iid, HRESULT hres ); HRESULT Error( UINT nid, const IID& iid, HRESULT hres, HINSTANCE hinst ); HRESULT Error( UINT nid, DWORD dwhelpid, LPCOLESTR lpszhelpfile, const IID& iid, HRESULT hres, HINSTANCE hinst ); STDMETHODIMP CStopwatch::Start() if ( QueryPerformanceCounter((LARGE_INTEGER*) &m_nstarttime) ) return S_OK; else return Error("High perf. counters not supported", IID_IStopwatch, tmerrorhighperformancetimersnotsupported);

Error() Jeżeli obiekt nie dziedziczy od CComCoClass globalnych funkcji AtlReportError: można użyć HRESULT AtlReportError( const CLSID& clsid, LPCOLESTR lpszdesc, const IID& iid, HRESULT hres ); HRESULT AtlReportError( const CLSID& clsid, LPCOLESTR lpszdesc, DWORD dwhelpid, LPCOLESTR lpszhelpfile, const IID& iid, HRESULT hres ); HRESULT AtlReportError( const CLSID& clsid, LPCSTR lpszdesc, const IID& iid, HRESULT hres ); HRESULT AtlReportError( const CLSID& clsid, LPCSTR lpszdesc, DWORD dwhelpid, LPCSTR lpszhelpfile, const IID& iid, HRESULT hres ); HRESULT AtlReportError( const CLSID& clsid, UINT nid, const IID& iid HRESULT hres, HINSTANCE hinst ); HRESULT AtlReportError( const CLSID& clsid, UINT nid, DWORD dwhelpid, LPCOLESTR lpszhelpfile, const IID& iid, HRESULT hres, HINSTANCE hinst );

Error() Gdy błędy zdefiniowano w pliku IDL jako stałe wyliczeniowe, można odczytać opis błędu (helpstring) bezpośrednio z biblioteki typów: #define SET_ERROR_INFO(hr) SerErrorInfo(hr, L#hr) HRESULT SetErrorInfo(HRESULT hr, WCHAR* ErrorName) HRESULT hresult; CComPtr<ITypeLib> ptypelib; CComPtr<ITypeInfo> ptypeinfo; USHORT NumberOfIds = 1; MEMBERID Id; unsigned long lhashval = 0; CComBSTR name(errorname); CComBSTR err_msg; hresult = AtlModuleLoadTypeLib(&_Module, 0, &(CComBSTR)NULL, &ptypelib); if (SUCCEEDED(hresult)) hresult =ptypelib->findname(name, 0, &ptypeinfo, &Id, &NumberOfIds); if (SUCCEEDED(hresult) && (Id!= MEMBERID_NIL)) hresult=ptypeinfo->getdocumentation(id, NULL, & err_msg, NULL, NULL); if (SUCCEEDED(hresult)) AtlReportError(CLSID_Stopwatch, err_msg, IID_IStopwatch, hr); return hresult;

IErrorInfo W celu odczytania rozszerzonej informacji o błędzie klient po sprawdzeniu czy użyty interfejs zwraca taką informację (ISupportErrorInfo:: InterfaceSupportErrorInfo()) może ją odczytać za pomocą funkcji GetErrorInfo() zwracającej wskaźnik do obiektu IErrorInfo. interface IErrorInfo: IUnknown HRESULT GetGUID( [out] GUID * pguid ); HRESULT GetSource( [out] BSTR * pbstrsource ); HRESULT GetDescription( [out] BSTR * pbstrdescription ); HRESULT GetHelpFile( [out] BSTR * pbstrhelpfile ); HRESULT GetHelpContext( [out] DWORD * pdwhelpcontext );

IErrorInfo //Raw interface error handling hr = pstopwatch->elapsedtime( &nelapsedtime ); if (SUCCEEDED(hr)) std::cout << "The overhead time is "<< nelapsedtime << std::endl; else ISupportErrorInfo* psupporterrorinfo; if (SUCCEEDED(pStopwatch->QueryInterface(IID_ISupportErrorInfo, (void**)&psupporterrorinfo))) if (psupporterrorinfo->interfacesupporterrorinfo(iid_istopwatch) == S_OK) IErrorInfo* perrorinfo; GetErrorInfo(0,&pErrorInfo); BSTR description; perrorinfo->getdescription(&description); wprintf(l"hresult = %x, Description: %s\n", hr, description); SysFreeString(description); perrorinfo->release(); psupporterrorinfo->release();

Smart pointers, _com_error Gdy klient wywołuje metody za pomocą inteligentnych wskaźników, a komponent zwrócił błąd, to zgłoszony zostaje zostaje wyjątek typu _com_error. Klasa _com_error zawiera w sobie pola HRESULT i IErrorInfo. // Constructors _com_error(hresult hr, IErrorInfo* perrinfo = NULL, bool faddref = false) throw(); _com_error(const _com_error& that) throw(); // Destructor virtual ~_com_error() throw(); // Assignment operator _com_error& operator=(const _com_error& that) throw();

_com_error // Accessors HRESULT Error() const throw(); IErrorInfo * ErrorInfo() const throw(); // IErrorInfo method accessors _bstr_t Description() const throw(_com_error); DWORD HelpContext() const throw(); _bstr_t HelpFile() const throw(_com_error); _bstr_t Source() const throw(_com_error); GUID GUID() const throw(); // FormatMessage accessors const TCHAR * ErrorMessage() const throw();

Komunikaty podczas debuggowania Do śledzenia działania programu zdefiniowano funkcję AtlTrace(LPCTSTR lpszformat,...) oraz makrodefinicje ATLTRACE() i ATLTRACE2(). Pozwalają one na wyświetlanie komunikatów w oknie debuggera. Podczas kompilacji w wersji release funkcje te nie podejmują żadnego działania.... catch (_com_error e) ATLTRACE(_T("ERROR(%d)", e.description()); std::cout<<"error(" << e.description() << ")";