R_5a-04.doc

(534 KB) Pobierz
Szablon dla tlumaczy

 

Rozdział 5                                                                                                                    Programowa obsługa interfejsu RS 232C w Windows

 

             

Czytając ten rozdział, zapoznasz się ze sposobami konstrukcji algorytmów, realizujących transmisję szeregową w środowisku Windows, które charakteryzuje się pewnymi cechami nie mającymi odpowiedników w MS DOS. Poznanie i umiejętne wykorzystanie tych cech sprawi, iż problem obsługi interfejsów szeregowych z poziomu Windows — uważany powszechnie za trudny — przestanie być dla nas tajemnicą. Pokażemy, w jaki sposób należy tworzyć aplikacje, służące do programowej obsługi łącza szeregowego RS 232C zarówno w C++Builderze jak i w Delphi. W moim odczuciu wśród programistów istnieje zauważalny podział na osoby programujące głównie w Delphi oraz na preferujące Buildera lub ogólnie C++ do Windows. Jednak zdaniem wielu osób uniwersalność jest jedną z tych zalet, jakie powinny charakteryzować programistę. W rozdziale tym przybliżymy Czytelnikowi podobieństwa i różnice w sposobie konstrukcji algorytmów realizujących transmisję szeregową, pisanych w Delphi oraz Builderze.

W dalszej części książki spotkamy się z typami danych, których poznanie i zrozumienie ma kluczowe znaczenie w projektowaniu aplikacji, obsługujących urządzenia zewnętrzne. Zacznijmy od ich przypomnienia. W tabeli poniżej przedstawiono porównanie podstawowych typów zmiennych wykorzystywanych w kompilatorach, które będą dla nas istotne. Większości z nich można używać zamiennie, pisząc zarówno w Delphi jak i w C++Builderze.

 

 

 

 

 

Tabela 5.1.

Typy zmiennych stosowanych w Delphi oraz w C++ Builderze

 

Delphi                         Rozmiar     /        Znak        /          Typ                                    C++ Builder                   

                       w bajtach               + / -  

 

ShortInt                              1                                                integer                                signed char                           

SmallInt                              2                                                integer                                          short                              

LongInt                              4                                                integer                              

Byte                              1                   bez znaku             integer                                      unsigned char             

Word                              2                   bez znaku             integer                                      unsigned short             

Integer                              4                                                integer                                             int                             

Cardinal                              4                   bez znaku             integer                                      unsigned int

Boolean                              1                   true/false                                                                         bool                           

ByteBool                                     true/false                                                                   unsigned char

                              1                   bez znaku             integer                                         

WordBool                                     true/false                                                         unsigned short

                              2                   bez znaku             integer                                                       

LongBool                                     true/false

                              4                    bez znaku            integer

AnsiChar                1               1 znak ANSI            character                                             char                           

WideChar                2              1 znak Unicode         character                                             wchar_t             

Char                              1                   bez znaku             character                                             char             

AnsiString       ≈3GB                 ANSIChar            AnsiString                                          AnsiString             

String[n]        n = 1..255             ANSIChar            string                                 SmallString<n>

                         bajtów

ShortString      255 bajtów         ANSIChar             string                                      SmallString<255>             

String                      255 lub ≈3GB      ANSIChar             AnsiString                                          AnsiString             

Single                              4                                                 floating point                           float

                                                                                  number

                                                                       (liczba  zmiennoprzecinkowa)

 

Double                              8                                                 floating point                           double

                                                                                  number                                                                         

Extended              10                                                floating point                           long double          

                                                                                  number                                                       

Real                              4                                                 floating point                           double

                                                                                  number                                                            

Pointer                              4                                                 generic pointer                         void *             

                                                                         (wskaźnik ogólny, adresowy)                         

PChar                              4                    bez znaku             pointer to characters                unsigned char *

                                                                        (daleki wskaźnik na C-łańcuch)       

PAnsiChar                4                    bez znaku              pointer to ANSIChar                 unsigned char *                                                                                                                                                                

Comp                              8                                                 floating point number               Comp              

Konstruując nasze programy, będziemy starali się jak najszerzej wykorzystywać standardowe zasoby Windows, w szczególności tzw. interfejs programisty Win 32 API (ang. Application Programming Interface). Jego umiejętne wykorzystanie umożliwi naszym aplikacjom błyskawiczne skonfigurowanie i uzyskanie dostępu do portu komunikacyjnego. Błędnym jest twierdzenie, że sama, nawet bardzo dobra znajomość języka programowania wystarczy, żeby stworzyć poprawnie działający w Windows program. Otóż musimy zdawać sobie sprawę z faktu, o którym często się zapomina — niemożliwe jest napisanie udanej aplikacji, mającej pracować w pewnym środowisku (czytaj — systemie operacyjnym), bez znajomości danego środowiska. Wiele już zostało powiedziane na temat dobrych i złych stron Windows, należy jednak pamiętać, że daje on nam swoją wizytówkę, ofertę współpracy, czyli API. Już nie wystarczy umiejętność wykorzystywania ulubionego kompilatora. Zasoby Delphi czy Buildera połączymy z zasobami systemu operacyjnego, a spoiwem tym będzie właśnie uniwersalne Win32 API. Istnieje wiele warstw API, używanych w zależności od potrzeb. W tym i dalszych rozdziałach zajmiemy się szeroko rozumianą warstwą komunikacyjną.     

Win32 API korzysta ze specjalnego systemu nazewnictwa zmiennych, z tzw. notacji węgierskiej wprowadzonej przez Węgra Karoja Szimoni’ego. Zgodnie z nią do rdzenia nazwy zadeklarowanej zmiennej dodaje się przedrostek (ang. prefix). Chociaż istnieją pod tym względem pewne rozbieżności pomiędzy nazewnictwem Microsoftu i Borlanda, to jednak zapis taki bardzo ułatwia szybkie ustalenie roli zmiennej w programie oraz jej typ. W następnych rozdziałach będziemy starali się — wszędzie gdzie jest to możliwe — zachowywać oryginalne, samokomentujące się nazewnictwo Win32 API (większość nazw API będziemy traktować jako nazwy własne). Z doświadczenia wiem, że stosowanie takiej konwencji bardzo pomaga w studiowaniu plików pomocy[1]. Oczywiście, moglibyśmy silić się na oryginalność, wprowadzając własne zmienne, zrozumiałe tylko dla piszącego dany program — wówczas przykłady musiałyby być zapisane jako wręcz humorystyczna mieszanina języków polskiego i angielskiego. Trzeba też przyznać, że byłby to bardzo skuteczny sposób zaciemnienia obrazu API. Zrozumienie znaczenia nazw tam stosowanych okaże się w przyszłości niezwykle cenne, gdyż API można czytać jak książkę. Aby pomóc Czytelnikom, którzy nie zetknęli się dotąd z tymi pojęciami,  poniżej przedstawiono ogólne zasady tworzenia niektórych przedrostków.

 

Tabela 5.2.

Ogólne zasady tworzenia przedrostków wg notacji węgierskiej.

 

Przedrostek             Skrót angielski                                                     Znaczenie

                                              

      a                          array                                                                      tablica

      b                          bool                                          zmienna logiczna TRUE lub FALSE  (1 lub 0)

      by                        byte unsigned char                                              znak (bajt)

      ch                        char                                                                        znak

      cb                        count of bytes                                                   liczba bajtów

      dw                       double word                                                     podwójne słowo

      evt                       event                                                                      zdarzenie

      f                          flag                                                                         znacznik

      fdw                     flag of double word                                           zacznik typu dw

      fn                        function                                                                   funkcja

      h                          handle                                                           identyfikator (uchwyt)

      i                           integer                                                        typ całkowity 4-bajtowy

      id                         (ID) identification                                              identyfikacja

      in                         input                                                                wejście, dane wejściowe      

      l                           long int                                                  typ całkowity długi 4-bajtowy

      lp                         long pointer                                                wskaźnik typu long int

      lpc                       long pointer to C- string                wskaźnik typu long int do C-łańcucha

      lpfdw                   long pointer to flag of dw        wskaźnik typu lp do znacznika typu double
                                                                                                                word

      lpfn                      long pointer to function                         wskaźnik typu lp do funkcji

      n                          short or int                                                   typ krótki lub całkowity

      np                        near pointer                                                         bliski wskaźnik

                                                                                         (w środowisku 32-bitowym to samo co lp)       

      out                       output                                                 wyjście, dane wyjściowe (przetworzone) 

      p                          pointer                                                                    wskaźnik

                                                                                         (w środowisku 32-bitowym to samo co lp)

      pfn                       pointer to function                                        wskaźnik do funkcji

      que                       queue                                                           kolejka, bufor danych

      s (sz)                    string                                                                  łańcuch znaków

      st                          struct                                                                        struktura 

      t                            type                                                                                            typ             

      u                           unsigned                                                                   bez znaku

      w                         (word) unsigned int                                                      słowo

      wc                        WCHAR                                                        znak zgodny z Unicode       

 

 

PRZYPOMNIJMY

Fizyczny adres pamięci w PC zaopatrzonym w procesor Pentium może składać się z segmentu i offsetu (tzw. przemieszczenia), określając tym samym możliwość istnienia wskaźników bliskich (ang. near pointer) i dalekich (ang. far pointer). Bliski wskaźnik, stanowiąc 32-bitowy adres efektywny, jest offsetem wewnątrz segmentu. Daleki wskaźnik stanowi 48-bitowy adres zawierając 16-bitowy selektor segmentu i 32-bitowy offset. Dalekie wskaźniki używane są w modelu segmentowym pamięci. Stosując metody zarządzania pamięcią, programy nie adresują w sposób bezpośredni pamięci fizycznej, adresują natomiast jej model. Win32 korzysta z płaskiego modelu pamięci (ang. flat memory model). W modelu tym segmenty mogą całkowicie pokrywać się z zakresami pamięci fizycznej lub z tymi jej adresami, które można mapować (odwzorowywać) do pamięci fizycznej. Wszystkie rejestry segmentowe podczas działania programu zawierają tą samą wartość – selektor odpowiedniego segmentu. W związku z tym wskaźniki stanowią 32-bitowe offsety w 4 GB segmencie (232 @ 4GB).  

 

Windows oferuje nam ponadto kilka typów danych, z których część tylko nieznacznie różni się sposobem zapisu w implementacjach Delphi i Buildera. Typy te mają najczęściej postać struktury lub klasy i są  bardzo często wykorzystywane w warstwie komunikacyjnej programów. Tabela 5.3 przedstawia przykładowe, ogólnie stosowane sposoby ich deklaracji.

   

 

 

 

Tabela 5.3. Typowe sposoby deklaracji stosowane w programach komunikacyjnych

 

                   Delphi                                       Znaczenie                                                 C++ Builder

 

               dcb :   TDCB;                struktura kontroli portu                              DCB   dcb;   

 

     hCommDev :  THANDLE;                32-bitowy identyfikator            HANDLE    hCommDev;

                                                          portu — jednorazowo

                                                          nadana wartość

                                                          identyfikująca port

             

       Stat :   TCOMSTAT;            struktura zawierająca                     COMSTAT    Stat;

                                                          dodatkowe informacje

                                                           o porcie szeregowym                           

 

Overlapped : TOVERLAPPED;  struktura zawierająca             OVERLAPPED  Overlapped;

                                                           informacje używane przy

                                                            transmisji asynchronicznej

...

Zgłoś jeśli naruszono regulamin