[ Pobierz całość w formacie PDF ]
.W nawiasach podanoodpowiednie, tradycyjnie stosowane oznaczenia.Przyk³ad:Oryginalna deklaracja w Win32 API:BOOL WriteFile(.,LPDWORD lpNumberOfBytesWritten,.);Z zapisu LPDWORD lpNumberOfBytesWritten odczytamy:lpNumberOfBytesWritten jest wskaŸnikiem i bêdzie wskazywaæ na dane typu DWORD.Wywo³anie:DWORD NumberOfBytesWritten;WriteFile(., &NumberOfBytesWritten ,.);Zmienna lub zmienne przekazywane w ten sposób do funkcji, np.WriteFile() musz¹byæ poprzedzone operatorem &, tak aby mog³y byæ utworzone odpowiedniewskaŸniki.Przy wykorzystaniu API w ten sposób dokonuje siê wywo³anie funkcji zprzekazywaniem argumentów przez adres.Konstrukcja segmentu wysy³aj¹cego komunikaty bêdzie jedn¹ z prostszych wnaszej aplikacji.Odzwierciedla jednak ogóln¹ metodê projektowania tego typuprogramów, w³aœciw¹ dla Win32 API.W naszej aplikacji segment ten przybierzepostaæ funkcji, do której bêdziemy mogli siê wielokrotnie odwo³ywaæ i pobieraæz niej tylko naprawdê potrzebne informacje.Je¿eli dok³adnie przeanalizujemyrolê wszystkich parametrów wystêpuj¹cych w funkcji WriteFile(), musimy dojœæ downiosku, ¿e tylko trzy pierwsze (czyli hCommDev — identyfikator portu, lpBuffer— wskaŸnik bufora danych, nNumberOfBytesToWrite — liczba bajtów do wys³ania) s¹naprawdê istotne, gdy¿ o liczbê bajtów faktycznie wys³anych zatroszcz¹ siê ju¿mechanizmy ochrony dla danych wysy³anych, zaimplementowane w funkcjiWriteFile().Kod naszej funkcji Write_Comm() zapisuj¹cej dane do portu bêdziemóg³ przyj¹æ nastêpuj¹c¹ uproszczon¹ postaæ:int __fastcall Write_Comm(HANDLE hCommDev, LPCVOID lpBuffer,DWORD nNumberOfBytesToWrite){DWORD NumberOfBytesWritten;if (WriteFile(hCommDev, lpBuffer, nNumberOfBytesToWrite,&NumberOfBytesWritten, NULL) > 0){WaitCommEvent(hCommDev, &fdwEvtMask, NULL);return TRUE;}elsereturn FALSE;}Zwróæmy jeszcze uwagê, ¿e nag³Ã³wek tej funkcji móg³by byæ równie dobrzezapisany tradycyjnie:int __fastcall Write_Comm(HANDLE hCommDev, const void *Buffer,DWORD nNumberOfBytesToWrite)lub nawet jako:int __fastcall Write_Comm(., void *Buffer,.)// LPVOID lpBufferDeklaruj¹c wskaŸnik bufora reprezentuj¹cego pewien obszar pamiêci operacyjnejprzy wysy³aniu danych, wcale nie musimy wskazywaæ na jakiœ sta³y obszar tejpamiêci, chocia¿ API w³aœnie to sugeruje.Pamiêtajmy, ¿e operujemy naC-³añcuchach.Je¿eli w buforze wyjœciowym znajdzie siê NUL bajt (nazywanyniekiedy zerowym ogranicznikiem) koñcz¹cy ³añcuch, nadawanie zostanieprzerwane.Nieco inaczej bêdzie to wygl¹da³o w przypadku danych odbieranych, cozostanie omówione za chwilê.PRZYPOMNIJMYDane typu LPVOID (void *), bêd¹c wskazaniami adresowymi, nie wskazuj¹ naobiekty.Lokalizuj¹ jedynie pewne obszary pamiêci operacyjnej.Pokazany sposób zapisu funkcji wysy³aj¹cej komunikaty do ³¹cza szeregowego niejest oczywiœcie jedynym z mo¿liwych.Mo¿na j¹ zapisaæ w sposób maksymalnieuproszczony, jedynie z dwoma parametrami formalnymi, które tak naprawdê s¹ dlanas najistotniejsze.Bêd¹ nimi: identyfikator portu oraz liczba bajtów dowys³ania:char Buffer_O[cbOutQueue]; // bufor danych wyjœciowych.int __fastcall Write_Comm(HANDLE hCommDev,DWORD nNumberOfBytesToWrite){.if (WriteFile(hCommDev, &Buffer_O[0],nNumberOfBytesToWrite, &NumberOfBytesWritten, NULL) > 0){.return TRUE;}elsereturn FALSE;}Je¿eli zdecydujemy siê na taki zapis, wówczas jednym z parametrów wywo³ywanejfunkcji API WriteFile() musi byæ jawnie u¿yty bufor danych wyjœciowychBuffer_O.Standardowo argumenty funkcji w C++ przekazujemy przez wartoœæ.W tensposób powodujemy utworzenie kopii argumentu w wywo³ywanej funkcji,zapobiegaj¹c tym samym mo¿liwoœci zmodyfikowania jego pocz¹tkowej wartoœci.Wprzypadku naszej funkcji Write_Comm() bêdzie to nNumberOfBytesToWrite, czyliliczba bajtów do wys³ania bêd¹ca jednoczeœnie parametrem funkcji Win32 APIWriteFile().Je¿eli z kolei funkcja ma zmodyfikowaæ wartoœci zmiennych bêd¹cychjej argumentami, parametry powinny byæ jawnie zadeklarowane jako wskaŸniki.Jest jeszcze wiele rzeczy, których nie uwzglêdniliœmy.Naprawdê niezawodnaaplikacja powinna mieæ parê dodatkowych zabezpieczeñ.Wszystkie je omówimy pokolei w nastêpnych podrozdzia³ach.Obecnie wa¿ne jest dla nas to, ¿e u¿yliœmywszystkich omówionych do tej pory funkcji Win32 API, poznaliœmy w jakiejkolejnoœci nale¿y je wywo³ywaæ.Po skompletowaniu ca³ego programu przekonaszsiê, ¿e mimo swojej prostoty bêdzie on funkcjonalny.Teraz, kiedy poznaliœmy, wjaki sposób mo¿na coœ „powiedzieæ” do urz¹dzenia, czas najwy¿szy, abyœmynauczyli siê „s³uchaæ” i „rozumieæ” jego odpowiedzi.Segment odbieraj¹cy komunikatyDRUGIE PRAWO SODDA:Wczeœniej czy póŸniej i tak musi nast¹piæ najgorszy z mo¿liwych splotówokolicznoœci.Uzupe³nienie:Ka¿dy system musi byæ zaprojektowany w taki sposób, aby stawiæ czo³anajgorszemu z mo¿liwych splotów okolicznoœci.Ka¿dy, kto kiedykolwiek interesowa³ siê komunikacj¹ komputerow¹ wie, ¿ewystêpowanie b³êdów w tym procesie jest czymœ nieuniknionym i poniek¹dnaturalnym.Ustalenie sposobu reagowania na wyst¹pienie b³êdu w czasietransmisji szeregowej jest zawsze bardzo istotnym elementem aplikacji.Przypominamy sobie z poprzednich rozdzia³Ã³w, ¿e istnieje pewien sposóbzabezpieczenia danych przed zafa³szowaniem w czasie ich przekazu.Sposobem tymjest kontrola bitu parzystoœci.Jest on jednak ma³o efektywny.Korzystaj¹c zzasobów struktury DCB, mo¿na w pewnym stopniu zabezpieczyæ siê przedodbieraniem przek³amanych danych.Wystarczy w czêœci konfiguracyjnej aplikacjiodwo³aæ siê do jednego ze znaczników DCB, a mianowicie do fAbortOnError (patrztabela 5.5.), pisz¹c:dcb.fAbortOnError = TRUE;co spowoduje wstrzymanie wykonywania wszelkich operacji wysy³ania i odbieraniadanych przy wykryciu jakiegokolwiek b³êdu w komunikacji z portem szeregowym.Reinicjalizacja odbioru i nadawania poprzez port komunikacyjny identyfikowanyprzez hCommDev nast¹pi po wywo³aniu funkcji:BOOL ClearCommError(HANDLE hCommDev,LPDWORD lpErrors,LPCOMSTAT lpStat);gdzie:lpErrors jest wskaŸnikiem do 32-bitowej danej typu DWORD, reprezentuj¹cej jedenz typów b³êdów:CE_BREAK — wykryto przerwanie po³¹czenia.CE_DNS — urz¹dzenie przy³¹czone do ³¹cza równoleg³ego nie zosta³o okreœlone(Win 9x).CE_FRAME — wyst¹pi³ b³¹d protoko³u ramki danych.CE_IOE — podczas komunikacji nast¹pi³ jakiœ b³¹d wejœcia-wyjœcia (Input-Output).CE_MODE — ¿¹danie nadawania nie jest podtrzymywane lub identyfikator portu(urz¹dzenia) ma b³êdn¹ specyfikacjê.CE_OOP — urz¹dzenie przy³¹czone do ³¹cza równoleg³ego sygnalizuje brak papieru,co jesttypowe dla drukarek, faksów, niektórych faksmodemów (Win 9x).CE_OVERRUN — nast¹pi³o ca³kowite wype³nienie wejœciowego bufora danych.Nastêpnyznak bêdzie zignorowany.CE_PTO — zosta³ przekroczony czas oczekiwania na po³¹czenie z portemrównoleg³ym, tzw.przeterminowanie czasu po³¹czenia (Win 9x).CE_RXOVER — bufor wejœciowy zosta³ przepe³niony
[ Pobierz całość w formacie PDF ]
Darmowy hosting zapewnia PRV.PL