2013-07-08 13 views
7

Czytałem napis na ścianie, Unikaj globów. Co prowadzi do oczywistego pytania, jak najlepiej to zrobić?Jak nie używać zmiennych globalnych w c

Oczywiście chcę to zrobić z bieżącym projektem. Celem jest umożliwienie odległemu komputerowi wysłania "naciśnięć klawiszy" do aplikacji, które mają już czytnik STID. Chodzi o to, aby istniejący kod wykrył, że nie ma oczekującego naciśnięcia klawisza, a następnie sprawdź, czy istnieje "naciśnięcie klawisza udp", a jeśli tak, zapakuj go tak, aby wyglądał jak wejście klawiaturowe. Minimalnie inwazyjny i nie będzie wymagał dopełnienia retro-dopasowania w kodzie innych osób.

Więc brukowane małą UDP czytelnika gniazda, która używa setup() funkcję otwierania i związać z portu, a następnie service() funkcję w pętli wykorzystującym nonblocking select() raz, bez pętli, wystarczy sprawdzić, czy jest coś do czytania w tej chwili. Jeśli tak, odczytywać dane z gniazdem i coś z tym zrobić, w przeciwnym wypadku zwraca 0.

// pseudo c 
char c; 

setup(); 
while (1) 
{ 
    c = check_for_keyboard_entry(); 
    if (c == 0) 
     c = service(); 
    handle_keypress(c); 
    do_a_bunch_of_other_stuff(); 
} 

Oczywistym sposobem na to jest z kilku globalnych przenieść port, limit czasu, sockaddr użytkownika itd. Między dwie funkcje. Ale chcesz zapalić globale, prawda?

Jaki jest preferowany sposób przeniesienia sześciu lub ośmiu znaków między funkcjami?

Gdybym użył vars statycznych w setup(), czy byłyby dostępne przez rutynę service()?

Przypuszczam, że struktura, która zostanie zdezynfekowana i przekazana będzie działać. Powinienem mieć cleanup(), aby zamknąć gniazdo i zwolnić pamięć.

PAMIĘTAJ, TO JEST C PYTANIE. NIE C++!

+2

_'' Przypuszczam, że struktura, która zostanie zdezynfekowana i przekazana będzie działać "" - Masz to! –

+0

+1 dla nieprzetworzonej prędkości! Jakieś inne podejścia? –

+1

Proszę naprawić \ 0 do 0 lub "\ 0" –

Odpowiedz

3

Możesz po prostu spakować wszystkie te informacje do numeru struct. Struktura może być widoczna dla klienta lub typu nieprzezroczystego. Typ nieprzezroczysty może być lepszym wyborem, dzięki czemu można ukryć dane (enkapsulacja) dla typów złożonych.

typedef struct { 
port_t port; 
timeout_t timeout; 
sockaddr_t sockaddr; 
etc_t etc; 
} my_stuff; 

następnie przekazać ją wokół odnośnik:

void Foo(my_stuff*); 

Przypuszczam struct, który pobiera malloc-ed i przeszedł wokół uda. Powinienem mieć funkcję czyszczenia(), aby zamknąć gniazdo i zwolnić pamięć.

Ogólnie rzecz biorąc, struktura nie zawsze musi być malloc "wyd. Ale tak, może to być przypadek, w którym jest to wymagane.

+0

Ale czy to nie sprawia, że ​​struktura jest globalna? Czy miałeś na myśli, że 'foo()' zwraca wskaźnik do 'my_stuff'? Jeśli tak, to w jaki sposób 'my_stuff' powtarza się, gdy zakres' foo() 'zostanie zamknięty? A może zrobiłbyś 'my_stuff' statyczny w' foo() '? –

+2

@WesMiller: Możesz umieścić go na stosie w zewnętrznym zasięgu. Więc 'int main() {moje rzeczy; stuff.port = 80; ...; Foo (i rzeczy); ...; return 0; } '. Zmienne statyczne w funkcjach SĄ de facto globalne i mają podobne problemy. –

+0

@MaciejPiechotka +1. Zasłużył sobie na zasłużony samobójczy policzek. Odpowiedź jest tak oczywista, gdy ją zobaczysz. –

Powiązane problemy