Difference between revisions of "Pierwsze tradycyjne "Hello world!""

From MorphOS Library

(Translation in progress.)
(Crosslink to English version.)
 
(One intermediate revision by the same user not shown)
Line 1: Line 1:
 
''Grzegorz Kraszewski''
 
''Grzegorz Kraszewski''
 +
----
 +
<small>Ta strona w innych językach: [[The First Traditional "Hello world!"|angielski]]</small>
  
  
Line 27: Line 29:
  
  
It can also be seen that many other libraries are also opened including ones related to TCP/IP networking. It looks like overkill for such a small program. This happens, because ''ixemul.library'' creates a complete unixlike environment for the application, which is not needed in this simple case. That is why the ''libnix'' alternative is recommended for use of the standard library. To use it, a '''&minus;noixemul''' option has to be added, so the compiler is called as follows:
+
Jak widać, program otwiera również inne biblioteki, nawet związane z komunikacją sieciową i stosem TCP/IP. Wygląda to na lekką przesadę, jak na taki prosty program. Dzieje się tak dlatego, że biblioteka ''ixemul.library'' tworzy programowi kompletne środowisko uniksopodobne, które w tym przypadku do niczego w gruncie rzeczy nie jest potrzebne. Dlatego zaleca się używanie statycznie linkowanej biblioteki ''libnix'' zamiast ''ixemul.library''. W tym celu dodajemy do wywołania kompilatora opcję '''&minus;noixemul''', będzie ono teraz wyglądało następująco:
  
 +
gcc -noixemul -o helloworld helloworld.c
  
<tt>gcc -noixemul -o helloworld helloworld.c</tt>
+
Wygenerowany plik wykonywalny jest teraz znacznie większy (na moim systemie 30 964 bajty), co potwierdza fakt, że tym razem użyte funkcje biblioteki standardowej zostały pobrane z ''libnix''-a i statycznie zlinkowane z programem, zwiększając tym samym jego rozmiar. Każdy podręcznik języka C mówi o tym, że ''printf()'' jest jedną z najkosztowniejszych (w sensie rozmiaru kodu) funkcji standardowego wejścia/wyjścia, co właśnie potwierdziliśmy eksperymentalnie... Z drugiej strony aktywność dyskowa programu została zredukowana do trzech linijek w ''Snoopium'', nasz program nie ładuje żadnych dodatkowych zasobów.
  
  
The generated executable is much larger (30 964 bytes here), which just confirms the fact, that ''libnix'', which is now in use, is a statically linked library. Size of functions used adds to the size of the executable. Every C handbook states, that ''printf()'' is the most expensive function of standard I/O, which has just been proven experimentally... On the other hand program activity, as traced with ''Snoopium'', is reduced to three entries. No external resources are opened.
+
=="Hello World!" z użyciem natywnego API systemu==
  
 +
MorphOS API (''Application Programmer Interface'') zawiera kompletną obsługę wejścia/wyjścia dla plików i konsoli tekstowej. W rzeczywistości funkcje z bibliotek standardowych C i C++ są mniej lub bardziej skomplikowanymi nakładkami na funkcje natywne. Bezpośrednie użycie funkcji natywnych ma następujące zalety:
  
=="Hello World!" With the MorphOS Native API==
+
* Programy są znacznie krótsze.
 +
* Programy są szybsze dzięki pominięciu dodatkowej warstwy abstrakcji.
 +
* Programy wymagają mniej zasobów (głównie pamięci).
 +
* Natywne API daje pełen dostęp do możliwości specyficznych dla MorphOS-a.
  
The MorphOS API (''Application Programmer Interface'') provides complete file and console input/output. In fact, functions in C and C++ standard libraries are, more or less, complex wrappers around MorphOS native calls. Using the native API has the following advantages:
 
  
* Programs are much shorter.
+
Ceną jaką za to płacimy jest utracenie przenośności kodu (z wyjątkiem &ndash; do pewnego stopnia &ndash; portów dla AmigaOS i AROS-a).
* Programs are faster, thanks to stripping some layers of abstraction.
 
* Programs are less resource hungry.
 
* Native API gives full access to MorphOS specific features.
 
  
  
These advantages come at a price:
+
Przykład "Hello World!" z użyciem natywnego API MorphOS-a wygląda jak następuje:
 
 
* Programs using the native API are not portable (except for porting to AmigaOS and AROS to some degree).
 
* Native ''printf()''-like functions do not support floating point numbers.
 
 
 
 
 
The "Hello World!" example using the native API is as follows:
 
 
 
 
 
<tt>#include <proto/dos.h><br><br>
 
int main(void)<br>
 
{<br>
 
&nbsp;&nbsp;Printf("Hello World!\n");<br>
 
&nbsp;&nbsp;return 0;<br>
 
}</tt>
 
 
 
 
 
The included header includes all things needed to use the ''dos.library'', where the ''Printf()'' function is located. The function itself works the same as the standard library ''printf()'', with some minor differences. The code is compiled with this command:
 
  
 +
#include <proto/dos.h>
 +
 +
int main(void)
 +
{
 +
  Printf("Hello World!\n");
 +
  return 0;
 +
}
  
<tt>gcc -noixemul -o helloworld helloworld.c</tt>
+
Dołączany plik nagłówkowy ''proto/dos.h'' zawiera wszystko, co potrzebne do użycia biblioteki współdzielonej ''dos.library'', zawierającej funkcję ''Printf()''. Funkcja ta działa tak samo jak standardowy ''printf()'' z kilkoma nieistotnymi zazwyczaj różnicami. Kod kompilujemy poleceniem:
  
 +
gcc -noixemul -o helloworld helloworld.c
  
The command is the same as that used for the program using ''libnix'' and the standard library ''printf()'', however, the standard C function is not used, so it is not linked. Now the executable size reduces to 13 500 bytes.
+
Polecenie jest takie samo jak dla programu używającego ''libnix''-a i standardowej funkcji ''printf()'', niemniej funkcja ta nie jest użyta, więc nie jest linkowana z programem. Dzięki temu rozmiar pliku wykonywalnego zmniejsza się do 13 500 bajtów.
  
  
Why is ''libnix'' still needed in spite of the standard library calls not being used? Can't one just compile with '''&minus;nostdlib'''? Other than the standard C library, ''libnix'' also provides application startup code. A program without this startup code can still work when launched from the shell, but will crash when started from Ambient. The startup code also provides an automatic MorphOS library opening and closing feature. So, excluding ''libnix'' completely is possible, but requires [[writing your own startup code]] and [[MorphOS_API_and_Its_Organization#Manual_Library_Opening_and_Closing|handling library opening and closing manually]].
+
Dlaczego wciąż potrzebujemy ''libnix''-a, mimo, że nie używamy w kodzie funkcji z biblioteki standardowej C? Czy nie można tego przykładu skompilować z opcją '''&minus;nostdlib'''? Niestety nie, bowiem ''libnix'' zapewnia tu nam nie tylko funkcje standardowe, ale także kod startowy programu. Program bez takiego kodu zostanie poprawnie wywołany z konsoli, ale zawiesi się, gdy uruchomimy go z poziomu Ambienta. Kod startowy zajmuje się również automatycznym otwieraniem i zamykaniem systemowych bibliotek współdzielonych. Całkowite pozbycie się ''libnix''-a jest zatem możliwe, ale wymaga napisania [[własnego kodu startowego]] oraz [[ręcznej obsługi bibliotek]].
  
  
<small>Note: excluding ''libnix'' is usually done for MorphOS components other than applications, like shared libraries or Reggae and MUI public classes. It can also be done for ordinary programs just to make them shorter, especially if a program is small. For bigger projects bytes saved by writing custom startup code are not usually worth the effort.</small>
+
<small>Uwaga: całkowita eliminacja biblioteki standardowej jest często wykonywana przy budowaniu komponentów systemu: bibliotek współdzielonych, czy klas publicznych MUI i Reggae. Można to zrobić również dla zwykłego programu aby uczynić go krótszym, szczególnie, jeśli program jest mały. Dla większych projektów zysk na rozmiarze pliku wykonywalnego uzyskany przez napisanie własnego kodu startowego jest zazwyczaj niewart włożonej dodatkowej pracy.</small>

Latest revision as of 14:42, 4 April 2011

Grzegorz Kraszewski


Ta strona w innych językach: angielski


"Hello World!" z użyciem biblioteki standardowej C

Używając biblioteki standardowej C, przykładowy program "Hello World!" możemy po prostu przepisać z podręcznika. Oto kod, dla przypomnienia:

#include <stdio.h>

int main(void)
{
  printf("Hello World!\n");
  return 0;
}

Kod źródłowy można skopiować do edytora tekstowego i zapisać jako helloworld.c. Aby go skompilować, otwieramy okno konsoli (z menu Ambienta, albo używając skrótu klawiszowego rcommand + n) i zmieniamy katalog bieżący na ten zawierający kod źródłowy. Uruchamiamy kompilator:

gcc -o helloworld helloworld.c

Kompilator stworzy plik wykonywalny helloworld, na moim systemie posiada on długość 10 340 bajtów. Warto zauważyć, że w MorphOS-ie rozszerzenia pilków nie są istotne więc dodanie .exe na końcu nazwy nie jest konieczne, chociaż możliwe. Tradycyjnie pliki wykonywalne w MorphOS-ie nie mają żadnego rozszerzenia nazwy. Opcja kompilatora −o specyfikuje nazwę tworzonego pliku wykonywalnego. Jeżeli opcja ta nie zostanie użyta, plik wynikowy zostanie nazwany a.out (z powodów historycznych).


Jak to opisano w rozdziale o SDK, biblioteka standardowa C jest dostarczana przez ixemul.library. Można to łatwo sprawdzić, śledząc aktywność dyskową programu za pomocą narzędzia Snoopium:


Snoopium ixemul.png


Jak widać, program otwiera również inne biblioteki, nawet związane z komunikacją sieciową i stosem TCP/IP. Wygląda to na lekką przesadę, jak na taki prosty program. Dzieje się tak dlatego, że biblioteka ixemul.library tworzy programowi kompletne środowisko uniksopodobne, które w tym przypadku do niczego w gruncie rzeczy nie jest potrzebne. Dlatego zaleca się używanie statycznie linkowanej biblioteki libnix zamiast ixemul.library. W tym celu dodajemy do wywołania kompilatora opcję −noixemul, będzie ono teraz wyglądało następująco:

gcc -noixemul -o helloworld helloworld.c

Wygenerowany plik wykonywalny jest teraz znacznie większy (na moim systemie 30 964 bajty), co potwierdza fakt, że tym razem użyte funkcje biblioteki standardowej zostały pobrane z libnix-a i statycznie zlinkowane z programem, zwiększając tym samym jego rozmiar. Każdy podręcznik języka C mówi o tym, że printf() jest jedną z najkosztowniejszych (w sensie rozmiaru kodu) funkcji standardowego wejścia/wyjścia, co właśnie potwierdziliśmy eksperymentalnie... Z drugiej strony aktywność dyskowa programu została zredukowana do trzech linijek w Snoopium, nasz program nie ładuje żadnych dodatkowych zasobów.


"Hello World!" z użyciem natywnego API systemu

MorphOS API (Application Programmer Interface) zawiera kompletną obsługę wejścia/wyjścia dla plików i konsoli tekstowej. W rzeczywistości funkcje z bibliotek standardowych C i C++ są mniej lub bardziej skomplikowanymi nakładkami na funkcje natywne. Bezpośrednie użycie funkcji natywnych ma następujące zalety:

  • Programy są znacznie krótsze.
  • Programy są szybsze dzięki pominięciu dodatkowej warstwy abstrakcji.
  • Programy wymagają mniej zasobów (głównie pamięci).
  • Natywne API daje pełen dostęp do możliwości specyficznych dla MorphOS-a.


Ceną jaką za to płacimy jest utracenie przenośności kodu (z wyjątkiem – do pewnego stopnia – portów dla AmigaOS i AROS-a).


Przykład "Hello World!" z użyciem natywnego API MorphOS-a wygląda jak następuje:

#include <proto/dos.h>

int main(void)
{
  Printf("Hello World!\n");
  return 0;
}

Dołączany plik nagłówkowy proto/dos.h zawiera wszystko, co potrzebne do użycia biblioteki współdzielonej dos.library, zawierającej funkcję Printf(). Funkcja ta działa tak samo jak standardowy printf() z kilkoma nieistotnymi zazwyczaj różnicami. Kod kompilujemy poleceniem:

gcc -noixemul -o helloworld helloworld.c

Polecenie jest takie samo jak dla programu używającego libnix-a i standardowej funkcji printf(), niemniej funkcja ta nie jest użyta, więc nie jest linkowana z programem. Dzięki temu rozmiar pliku wykonywalnego zmniejsza się do 13 500 bajtów.


Dlaczego wciąż potrzebujemy libnix-a, mimo, że nie używamy w kodzie funkcji z biblioteki standardowej C? Czy nie można tego przykładu skompilować z opcją −nostdlib? Niestety nie, bowiem libnix zapewnia tu nam nie tylko funkcje standardowe, ale także kod startowy programu. Program bez takiego kodu zostanie poprawnie wywołany z konsoli, ale zawiesi się, gdy uruchomimy go z poziomu Ambienta. Kod startowy zajmuje się również automatycznym otwieraniem i zamykaniem systemowych bibliotek współdzielonych. Całkowite pozbycie się libnix-a jest zatem możliwe, ale wymaga napisania własnego kodu startowego oraz ręcznej obsługi bibliotek.


Uwaga: całkowita eliminacja biblioteki standardowej jest często wykonywana przy budowaniu komponentów systemu: bibliotek współdzielonych, czy klas publicznych MUI i Reggae. Można to zrobić również dla zwykłego programu aby uczynić go krótszym, szczególnie, jeśli program jest mały. Dla większych projektów zysk na rozmiarze pliku wykonywalnego uzyskany przez napisanie własnego kodu startowego jest zazwyczaj niewart włożonej dodatkowej pracy.