5. Funkcje własne.

5.16. Biblioteki funkcji: część 4

W dwóch poprzednich rozdziałach omówiliśmy podłączenie biblioteki za pomocą dyrektywy #import. Istnieje jeszcze jeden sposób, gdzie bibliotekę można podłączyć za pomocą dyrektywy #include.

Utwórzmy plik nowej biblioteki w folderze Include, zgodnie z procedurą opisaną w rozdziale 5.13. Biblioteki funkcji: część 1, tylko teraz w okienku MQL Wizard wybierz typ Uwzględnij (*.mqh) (rys. 1). Po angielsku to będzie Include (*.mqh).

Rys. 1. Biblioteka include.


Plik biblioteki nazwijmy na przykład MyLibrary, który następnie pojawi się w folderze Include (rys. 2).

Rys. 2. Biblioteka include.


W pliku tej biblioteki zapiszmy funkcję do obliczenia objętości walca (kod 1), który wielokrotnie używaliśmy w poprzednich przykładach.

Kod 1
#property strict

//--- funkcja do obliczenia objętości walca
double CylinderVolume(double radius, double height)
  {
   double volume = M_PI * radius * radius * height;
   return(volume);
  }

Zwróć uwagę, że nie piszemy tu #property library oraz po prawej stronie od nagłówka funkcji nie trzeba też pisać export. Teraz żeby do naszego skryptu Test podłączyć tę include-bibliotekę na początku skryptu należy zapisać tylko jeden wiersz (kod 2).

Kod 2
#property strict

//--- Podłączenie biblioteki
#include <MyLibrary.mqh>

void OnStart()
  {
   double r = 1.0;
   double h = 2.5;
   double v = CylinderVolume(r, h);
   Print("Objętość walca = ", DoubleToString(v));
  }

Tutaj widać, że podłączenie biblioteki zaczyna się od dyrektywy #include, po której między ostrymi nawiasami < > należy zapisać nazwę pliku wraz z jego rozszerzeniem *.mqh (kod 3).

Kod 3
//--- Podłączenie biblioteki
#include <MyLibrary.mqh>

W odróżnieniu od dyrektywy #import, nie musimy teraz każdą funkcję z biblioteki importować indywidualnie. Kompilator będzie wiedział, że z biblioteki o nazwie MyLibrary.mqh, znajdującej się w folderze Include do programu należy podłączyć funkcję o nazwie CylinderVolume(). Jeśli program będzie potrzebował z biblioteki wiele funkcji, to ich podłączenie można załatwić tylko tą jedną linijką kodu. Jeśli kompilator w folderze Include nie znajdzie pliku o nazwie MyLibrary.mqh, to nie będzie go nigdzie dalej szukać, a od razu w MetaEditor 4 wywali błąd, że nie może otworzyć pliku.

Jeśli zamiast ostrych nawiasów < > nazwę pliku biblioteki zapiszemy w cudzysłowach "" (kod 4), wtedy kompilator będzie szukać bibliotekę tylko w tym folderze, gdzie znajduje się plik programu.

Kod 4
//--- Podłączenie biblioteki
#include "MyLibrary.mqh"

Na przykład dla pliku automatycznej strategii, znajdującego się w folderze Experts, kompilator będzie szukać bibliotekę tylko w tym folderze. Dla pliku wskaźnika w folderze Indicators odpowiednio tylko w tym folderze. Dla skryptów w folderze Scripts zadziała ten sam mechanizm. Oczywiście, jeśli plik programu będzie znajdować się w jakimś innym folderze, to i plik biblioteki musiał by znajdować się w tym folderze.


Jeśli popatrzysz na zawartość folderu Include, to znajdziesz tam wiele pod-folderów i ważnych systemowych plików bibliotek funkcji oraz klas. Aby zostawić to wszystko w nienaruszonym stanie najlepiej utworzyć nowy pod-folder, w którym będziemy płodzić wszystkie nasze biblioteki. Dla przykładu utwórzmy tam folder o nazwie Kontener, do którego przenieśmy plik include-biblioteki MyLibrary.mqh. Aby podłączyć taką bibliotekę do programu, między < > najpierw należy zapisać nazwę folderu, potem lewy ukośnik \ i nazwę pliku wraz z rozszerzeniem *.mqh (kod 5).

Kod 5
//--- Podłączenie biblioteki
#include <Kontener\MyLibrary.mqh>

Jeśli będziesz potrzebował podłączyć kolejną bibliotekę to po prostu jeszcze raz zapisz dyrektywę #include, a po niej adres pliku (kod 6).

Kod 6
//--- Podłączenie wielu bibliotek z folderu Include
#include <nazwa_pod-folderu\nazwa_pliku_1.mqh>
#include <nazwa_pod-folderu\nazwa_pliku_2.mqh>
...
#include <nazwa_pod-folderu\nazwa_pliku_N.mqh>

Podłączając kilka bibliotek, trzeba uważać żeby dwie biblioteki nie zawierały funkcji o takiej samej nazwie. Jeśli tak się stanie, to podczas kompilacji zostanie wyświetlony błąd typu: 'CylinderVolume' - function already defined and has body, tj. funkcja o nazwie CylinderVolume już jest zdefiniowana i ma ciało.


Jeśli porównywać dyrektywy #import i #include pod kątem wygody podłączenia bibliotek, to zdecydowanie polecam #include.