CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - Metody obsługi wyjątków

Metody obsługi wyjątków

dział ogólny

Metody obsługi wyjątków

Postprzez Slynx » czwartek, 19 maja 2011, 00:29

Jest jakiś inny sposób na wyłapanie wyjątku oprócz bloku try catch ?
Mam na myśli konkretną funkcję, np.
KOD cpp:     UKRYJ  
Convert::FromBase64String
 

która może zwrócić dwa wyjątki
Kod: Zaznacz cały
ArgumentNullException   

FormatException   

Ja wiem, że u mnie wystąpi FormatException. Można to obsłużyć w inny sposób ?
Avatar użytkownika
Slynx
Mądrosław
Mądrosław
 
Posty: 350
Dołączył(a): piątek, 17 grudnia 2010, 21:59
Podziękował : 11
Otrzymał podziękowań: 0
System operacyjny: Windows 7 32
Kompilator: Visual C++ 2005; Visual C++ 2008; Visual C++ 2010; Visual C# 2010;
Gadu Gadu: 0
    Windows 7Chrome

Re: Metody obsługi wyjątków

Postprzez Cyfrowy Baron » czwartek, 19 maja 2011, 08:01

Masz funkcję GetLastError, która pobiera ostatni błąd jaki wystąpił. Można do tego celu stworzyć sobie własną funkcję

KOD cpp:     UKRYJ  
void ErrorExit(String lpFun)
{
   LPVOID lpMsgBuf;
    LPVOID lpDisplayBuf;

    DWORD dw = GetLastError();

    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER |
        FORMAT_MESSAGE_FROM_SYSTEM,
        NULL,
        dw,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR) &lpMsgBuf,
        0, NULL );

    lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
                (lstrlen((LPCTSTR)lpMsgBuf)+lstrlen(lpFun.t_str())+40)*sizeof(TCHAR));
    wsprintf((LPTSTR)lpDisplayBuf,
        TEXT("%s failed with error %d: %s"),
                lpFun, dw, lpMsgBuf);
        MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);

    LocalFree(lpMsgBuf);
    LocalFree(lpDisplayBuf);
        ExitProcess(dw);
}


Wywołuje się ją w kodzie, gdzie może wystąpić wyjątek, np:

KOD cpp:     UKRYJ  
void __fastcall CloseProcess(String ProcesName)
{
 DWORD ExitCode;
 HANDLE Snap;
 PROCESSENTRY32 proces;

 Snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
 proces.dwSize = sizeof(PROCESSENTRY32);

 if(Process32First(Snap, &proces))
 {
  do
  {
   if(proces.szExeFile[0] != '[')
   {
        if(SameText(proces.szExeFile, ProcesName))
        {

         TOKEN_PRIVILEGES tPriv;
         LUID luid;

         HANDLE hWndTok;
         if(!OpenProcessToken(GetCurrentProcess(),
                 TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hWndTok))
         {
                        ErrorExit("OpenProcessToken: "); /* TUTAJ */
         }

         if(!LookupPrivilegeValue(NULL, "SeDebugPrivilege", &luid ))
          ErrorExit("LookupPrivilegeValue: "); /* TUTAJ */

         tPriv.PrivilegeCount = 1;
         tPriv.Privileges[0].Luid = luid;
         tPriv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

         if(!AdjustTokenPrivileges(hWndTok, false, &tPriv,
                                                          sizeof(TOKEN_PRIVILEGES),
                                                          (PTOKEN_PRIVILEGES) NULL,
                                                          (PDWORD) NULL))
         {
          ErrorExit("AdjustTokenPrivileges: "); /* TUTAJ */
         }

         HANDLE hWnd = OpenProcess(PROCESS_ALL_ACCESS, false, proces.th32ProcessID);
         if(GetLastError() > 0) ErrorExit("OpenProcess: ");
         if(hWnd)
         {
          GetExitCodeProcess(hWnd, &ExitCode);
          TerminateProcess(hWnd, ExitCode);
         }
         CloseHandle(hWnd);
         return;
         }
        }
   }while(Process32Next(Snap , &proces));
 }
 CloseHandle(Snap);
}
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Metody obsługi wyjątków

Postprzez Slynx » czwartek, 19 maja 2011, 09:04

Z tym to więcej zachodu niż to warte. Lepiej pozostać przy try catch. Wadą tego jest konieczność wcześniejszych deklaracji zmiennych jeśli chce się ich użyć wewnątrz kodu i poza nim, ale na razie to najlepszy sposób.
----
Na razie staram się coś zrobić z moim kodem do "przefiltrowania" Stringa (100KB), bo czas jaki mu to zajmuje (ok 6s) jest "trochę" za duży.
Avatar użytkownika
Slynx
Mądrosław
Mądrosław
 
Posty: 350
Dołączył(a): piątek, 17 grudnia 2010, 21:59
Podziękował : 11
Otrzymał podziękowań: 0
System operacyjny: Windows 7 32
Kompilator: Visual C++ 2005; Visual C++ 2008; Visual C++ 2010; Visual C# 2010;
Gadu Gadu: 0
    Windows 7Chrome

Re: Metody obsługi wyjątków

Postprzez Cyfrowy Baron » czwartek, 19 maja 2011, 09:10

Metoda GetLasError ma zastosowanie tam, gdzie try catch się nie sprawdzi, gdzie chcesz otrzymać dokładne informacje o błędzie, czyli o miejscu w którym wystąpił oraz dokładną treść błędu. GetLastError wyłapuje błędy dla których np. jakaś funkcja nie może być zrealizowana, a try catch wyłapuje wyjątki.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Metody obsługi wyjątków

Postprzez Slynx » czwartek, 19 maja 2011, 09:45

try catch też wyłapuje dokładną treść błędy, wystarczy zrobić "catch(Exception ^e)", z zmienna "e" będzie zawierała wszystkie informacje o błędzie. Informacje dotyczące funkcji, linia w kodzie, wszystko.
Avatar użytkownika
Slynx
Mądrosław
Mądrosław
 
Posty: 350
Dołączył(a): piątek, 17 grudnia 2010, 21:59
Podziękował : 11
Otrzymał podziękowań: 0
System operacyjny: Windows 7 32
Kompilator: Visual C++ 2005; Visual C++ 2008; Visual C++ 2010; Visual C# 2010;
Gadu Gadu: 0
    Windows 7Chrome

Re: Metody obsługi wyjątków

Postprzez polymorphism » czwartek, 19 maja 2011, 10:00

Jest jakiś inny sposób na wyłapanie wyjątku oprócz bloku try catch ?

Odpowiedź krótka: nie. Jeśli funkcja rzuca wyjątkiem, powinieneś go obsłużyć, jeżeli nie chcesz, żeby wyłożył aplikację.

Odnośnie GetLastError, dotyczy ona praktycznie tylko funkcji WinAPI. Operując na klasach .NET'owych, zapomnij o niej, bo nie ma tu żadnego zastosowania.

Na razie staram się coś zrobić z moim kodem do "przefiltrowania" Stringa (100KB), bo czas jaki mu to zajmuje (ok 6s) jest "trochę" za duży.

100KB i 6 sekund?! To co to za kod filtrujący?
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Metody obsługi wyjątków

Postprzez Cyfrowy Baron » czwartek, 19 maja 2011, 10:04

Nie o to mi chodziło. Niektóre funkcję wymagają użycia metody GetLastError. Weźmy np. taki kod:

KOD cpp:     UKRYJ  
if(!LookupPrivilegeValue(NULL, "SeDebugPrivilege", &luid ))
          ErrorExit("LookupPrivilegeValue: "); /* TUTAJ */


Jeżeli działanie funkcji LookupPrivilegeValue się nie powiedzie, to zwróci ona kod błędu i tylko GetLastError go wyłapie. Umieszczenie tego kodu w bloku try catch nic nie da, gdyż niezależnie od efektu funkcja wykona zadanie.

W pliku pomocy dla tej funkcji masz:


Return Value

If the function succeeds, the function returns nonzero.

If the function fails, it returns zero. To get extended error information, call GetLastError.




Jak widzisz funkcja zawsze zwraca jakąś wartość, a w przypadku, gdy nie może wykonać działania zwraca 0. W bloku try catch nie wyłapiesz jaki to błąd.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Metody obsługi wyjątków

Postprzez polymorphism » czwartek, 19 maja 2011, 10:34

Nie no, dobra. Tylko od początku jest mowa o (innej) obsłudze wyjątków w kontekście .NET'owej funkcji FromBase64String, która błędy zgłasza wyjątkiem. GetLastError jest archaicznym sposobem komunikowania o błędzie, typowym dla języka C, gdzie nie ma takiego mechanizmu wyjątków, jaki masz np. w C++, nie wspominając o C# czy Javie.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Metody obsługi wyjątków

Postprzez Cyfrowy Baron » czwartek, 19 maja 2011, 10:37

polymorphism napisał(a):GetLastError jest archaicznym sposobem komunikowania o błędzie, typowym dla języka C, gdzie nie ma takiego mechanizmu wyjątków, jaki masz np. w C++,


Przecież GetLastError występuje w C++. Skoro ta metoda w C++ jest archaiczna, to co nowego jest w C++?! W pomocy dla wszystkich funkcji podawana jest właśnie ta metoda.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Metody obsługi wyjątków

Postprzez polymorphism » czwartek, 19 maja 2011, 11:04

Przecież GetLastError występuje w C++.

Nie w C++, tylko w WinAPI. A WinAPI w głównej mierze jest interfejsem systemowym pisanym pod C. No a że C++ jest zgodny z C'89(?), więc masz tę funkcję także w C++ - oczywista oczywistość.

Skoro ta metoda w C++ jest archaiczna, to co nowego jest w C++?!

Wyjątki ;) Co prawda w praktyce nie przyjęły się zbytnio, być może z racji kiepskiej (lub żadnej) przenośności, no ale koncepcyjnie była to nowość. W językach zarządzanych wyjątki są powszechną metodą zgłaszania błędów.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Metody obsługi wyjątków

Postprzez Cyfrowy Baron » czwartek, 19 maja 2011, 11:10

polymorphism napisał(a):Nie w C++, tylko w WinAPI. A WinAPI w głównej mierze jest interfejsem systemowym pisanym pod C


Trudno mi uznać za archaiczne, to co jest powielane w kolejnych edycjach systemu Windows. Środowisko Embarcadero RAD Studio 2010, nie jest przestarzałe i w pełni zgodne z VISTĄ, i wciąż korzysta z tej metody. Czy w WinAPI pojawiło się coś co zastępuje tą metodę.

Platformy .NET-owe też miały być czymś rewolucyjnym, gwarantującym przenośność aplikacji między systemami, a dziś .NET Framework jest raczej dodatkiem do systemu niż zamiennikiem dla API.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Metody obsługi wyjątków

Postprzez polymorphism » czwartek, 19 maja 2011, 11:30

Czy w WinAPI pojawiło się coś co zastępuje tą metodę.

Jak już wcześniej pisałem, WinAPI jest interfejsem pisanym pod C, zatem nic nowego tutaj nie może się pojawić.

Platformy .NET-owe też miały być czymś rewolucyjnym, gwarantującym przenośność aplikacji między systemami

Nie mogły być rewolucyjne, ponieważ wcześniej była Java, i tak na prawdę to ona zgarnęła większą część rynku.

a dziś .NET Framework jest raczej dodatkiem do systemu niż zamiennikiem dla API.

Owszem jest, ale są plany, żeby zupełnie zastąpić stare API właśnie .NET'em. Z oczywistych względów nie zrobią tego z dnia na dzień, z wersji na wersję, ale taka jest tendencja i kierunek zmian. W Viście i W7 .NET framework jest częścią systemu. Zresztą przejrzyj sobie oferty pracy, programista C#, czy po prostu piszący pod .NET'em, jest bardziej pożądany niż programista C++.

Prawda jest taka, że języki zarządzane to przyszłość.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Metody obsługi wyjątków

Postprzez Slynx » czwartek, 19 maja 2011, 11:45

100 KB i 6 sekund.... no sam byłem zaskoczony, ale tekst jest na tyle "złośliwy", że aby wyłapać odpowiedni fragment trzeba ciąć kilkukrotnie, w końcu wyłapać potrzebną treść, spróbować zdekodować (czyli właśnie to "FromBase64String") jeśli się powiedzie, to odpalić całą funkcje dekodowania, a jeśli nie to przejść dalej. I tak trzeba przelecieć przez cały dukument, dlatego uznałem, że wyrażenia regularne będą znacznie lepsze. Od razu wyciąć wszystkie wystąpienia odpowiedniego kawałku kodu i już potem nie operować na tym 100 kilobajtowym pliku.
Jest też trochę problem właśnie za tym dekodowaniem, bo to zajmuje znaczną część czasu. Kod do zdekodowania ma może 20-30 znaków, ale jeśli całą funkcję trzeba wykonać 100 razy... Bardzo możliwe, że będę musiał zmienić sposób kodowania tekstu na szybszy (rot13 czy zwykłe xor-owanie). Problem bez wątpienia jest bo 6 s robić coś takiego... a to zaledwie część dużej operacji... ehh..
Avatar użytkownika
Slynx
Mądrosław
Mądrosław
 
Posty: 350
Dołączył(a): piątek, 17 grudnia 2010, 21:59
Podziękował : 11
Otrzymał podziękowań: 0
System operacyjny: Windows 7 32
Kompilator: Visual C++ 2005; Visual C++ 2008; Visual C++ 2010; Visual C# 2010;
Gadu Gadu: 0
    Windows 7Chrome

Re: Metody obsługi wyjątków

Postprzez Slynx » piątek, 20 maja 2011, 19:36

No, udało się. ostatecznie zszedłem z 6 sekund do znośnej sekund (~0,8), sam kod się skrócił co najmniej o połowę.
Avatar użytkownika
Slynx
Mądrosław
Mądrosław
 
Posty: 350
Dołączył(a): piątek, 17 grudnia 2010, 21:59
Podziękował : 11
Otrzymał podziękowań: 0
System operacyjny: Windows 7 32
Kompilator: Visual C++ 2005; Visual C++ 2008; Visual C++ 2010; Visual C# 2010;
Gadu Gadu: 0
    Windows 7Chrome


  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Ogólne problemy z programowaniem

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 5 gości

cron