Nowe posty

Autor Wątek: gnuplot API C++ - rysowanie wykresów  (Przeczytany 10002 razy)

cod3r

  • Gość
gnuplot API C++ - rysowanie wykresów
« dnia: 2011-05-02, 18:10:34 »
Witam,
Pobrałem sobie API gnuplot++ (link: http://www.suiri.tsukuba.ac.jp/~asanuma/gnuplot++/) i chciałem się pobawić trochę w rysowanie wykresów przy jego pomocy. Na stronie jest udostępnionych kilka przykładowych programów, natomiast kompilacja każdego z tych przykładów kończy się sporą ilością błędów.
Pierwszy z brzegu przykład:
#include 
#include
#include
#include
#include "gnuplotpp.h"

using namespace std;
using namespace gnuplotpp;

int main( void ){

 singleplot g;

 g.set("term png" );
 g.set() << gpset( "output", "\\"demo1.png\\"" ) << endl;

 g.x.label( "x axis" ).format( "%03.2f" ).tics(0.2).mtics(.05);
 g.y.label( "y axis" );

 g.label( "simgle plot example", coord( "graph 0.5", "graph 0.5" ) );

 g.arrow( coord( "graph 0.5", "graph 0.5" ), coord( "graph 1", "graph 1" ) );

 g.plotfile( "data.dat", 1, 2 )<< " t 'data'" << " pt 1" ;

 g.plotfunc( "x" ) ;

 g.save( "demo1.gp" ).exec();

}
Wynik kompilacji:
In file included from plikdemo1.cpp:5:
gnuplotpp.h:9: warning: deprecated conversion from string constant to ‘char*’
In file included from gnuplotpp.h:12,
                 from plikdemo1.cpp:5:
gp_components.h:9: warning: deprecated conversion from string constant to ‘char*’
In file included from gnuplotpp.h:23,
                 from plikdemo1.cpp:5:
gp_plot.h:9: warning: deprecated conversion from string constant to ‘char*’
In file included from gp_plot.h:15,
                 from gnuplotpp.h:23,
                 from plikdemo1.cpp:5:
gp_base.h:9: warning: deprecated conversion from string constant to ‘char*’
In file included from gp_plot.h:17,
                 from gnuplotpp.h:23,
                 from plikdemo1.cpp:5:
gp_traits.h:9: warning: deprecated conversion from string constant to ‘char*’
In file included from gp_plot.h:18,
                 from gnuplotpp.h:23,
                 from plikdemo1.cpp:5:
gp_subplot.h:9: warning: deprecated conversion from string constant to ‘char*’
/tmp/cc39MOzR.o: In function `main':
plikdemo1.cpp:(.text+0x16): undefined reference to `gnuplotpp::detail::singleplot::singleplot()'
plikdemo1.cpp:(.text+0xc2): undefined reference to `gnuplotpp::detail::axis::label(char const*) const'
plikdemo1.cpp:(.text+0xd2): undefined reference to `gnuplotpp::detail::axis::format(char const*) const'
plikdemo1.cpp:(.text+0xe4): undefined reference to `gnuplotpp::detail::axis::tics(double) const'
plikdemo1.cpp:(.text+0xf6): undefined reference to `gnuplotpp::detail::axis::mtics(double) const'
plikdemo1.cpp:(.text+0x10d): undefined reference to `gnuplotpp::detail::axis::label(char const*) const'
plikdemo1.cpp:(.text+0x14b): undefined reference to `gnuplotpp::detail::plotbase::label(char const*, gnuplotpp::detail::gpcoord const&)'
plikdemo1.cpp:(.text+0x1d8): undefined reference to `gnuplotpp::detail::plotbase::arrow(gnuplotpp::detail::gpcoord const&, gnuplotpp::detail::gpcoord const&)'
plikdemo1.cpp:(.text+0x2a0): undefined reference to `gnuplotpp::detail::filebase::save(char const*)'
plikdemo1.cpp:(.text+0x2a8): undefined reference to `gnuplotpp::detail::filebase::exec() const'
/tmp/cc39MOzR.o: In function `gnuplotpp::detail::singleplot::~singleplot()':
plikdemo1.cpp:(.text._ZN9gnuplotpp6detail10singleplotD1Ev[gnuplotpp::detail::singleplot::~singleplot()]+0xd): undefined reference to `vtable for gnuplotpp::detail::singleplot'
plikdemo1.cpp:(.text._ZN9gnuplotpp6detail10singleplotD1Ev[gnuplotpp::detail::singleplot::~singleplot()]+0x1a): undefined reference to `vtable for gnuplotpp::detail::singleplot'
plikdemo1.cpp:(.text._ZN9gnuplotpp6detail10singleplotD1Ev[gnuplotpp::detail::singleplot::~singleplot()]+0x27): undefined reference to `vtable for gnuplotpp::detail::singleplot'
/tmp/cc39MOzR.o: In function `gnuplotpp::detail::subplot::subplot, std::allocator > >(std::basic_string, std::allocator >, int, int)':
plikdemo1.cpp:(.text._ZN9gnuplotpp6detail7subplotC2ISsEET_ii[gnuplotpp::detail::subplot::subplot, std::allocator > >(std::basic_string, std::allocator >, int, int)]+0x5e): undefined reference to `gnuplotpp::detail::gpusing::gpusing(int, int)'
/tmp/cc39MOzR.o: In function `gnuplotpp::detail::subplot::subplot(char const*, int, int)':
plikdemo1.cpp:(.text._ZN9gnuplotpp6detail7subplotC2IPKcEET_ii[gnuplotpp::detail::subplot::subplot(char const*, int, int)]+0x5e): undefined reference to `gnuplotpp::detail::gpusing::gpusing(int, int)'
collect2: ld returned 1 exit status
Ostrzeżeniami to bym się raczej nie przejmował, natomiast nie rozumiem dlaczego przy singleplot g; jest coś nie tak, jak napiszę singleplot& g; to praktycznie wszystkie błędy znikają ale pojawia się jeden mówiący o braku inicjalizacji.

error: ‘g’ declared as reference but not initialized
Prosiłbym kogoś kto ma w tym jakieś doświadczenie o podzielenie się wiedzą co tutaj jest nie halo, patrząc po dacie tego API to jest dość stare czyżby jakiś brak zgodności?

Offline Paweł Kraszewski

  • Administrator
  • Guru
  • *****
  • Wiadomości: 3066
  • Lenistwo jest matką potrzeby = babcią wynalazku
    • Zobacz profil
gnuplot API C++ - rysowanie wykresów
« Odpowiedź #1 dnia: 2011-05-02, 19:25:21 »
Błędy są z fazy linkowania. Czy do podanego kodu linkujesz właściwą bibliotekę C++?
Paweł Kraszewski
~Arch/Void/Gentoo/FreeBSD/OpenBSD/Specjalizowane customy

cod3r

  • Gość
gnuplot API C++ - rysowanie wykresów
« Odpowiedź #2 dnia: 2011-05-02, 19:35:25 »
Dołączam biblioteki które widać. Nie wiem czy jest konieczność linkowania jeszcze jakoś bezpośrednio przy kompilacji? Plik gnuplotpp.h zawiera inne pliki nagłówkowe z deklaracjami klas/funkcji więc wydaje mi się że nie ma konieczności "inkludowania" wszystkich możliwych plików.
Kompiluję poleceniem: g++ -o plikdemo1 plikdemo1.cpp nie wiem czy trzeba tutaj przy polecaniu kompilacji jeszcze coś dolinkowywać?

Offline Paweł Kraszewski

  • Administrator
  • Guru
  • *****
  • Wiadomości: 3066
  • Lenistwo jest matką potrzeby = babcią wynalazku
    • Zobacz profil
gnuplot API C++ - rysowanie wykresów
« Odpowiedź #3 dnia: 2011-05-03, 11:29:52 »
Tutaj dołączasz pliki nagłówkowe, nie biblioteki. Plik nagłówkowy to tylko obietnica, że w fazie linkowania pojawi się plik obiektu/biblioteki spełniający obietnicę.

Generalnie procedura jest taka:
1. Ściągasz bibliotekę użytkową, dajmy na to Twoje gnuplot++.
2. W jej skład (normalnie) wchodzi plik make'a, nagłówki i zwykłe pliki źródłowe.
3. Uruchomiony plik make powinien skompilować pliki źródłowe do biblioteki (np. libgnuplotpp.a), skopiować ją do katalogu /usr/lib albo /usr/local/lib oraz skopiować pliki nagłówkowe do katalogu odpowiednio /usr/include bądź /usr/local/include.
4. W swoim programie włączasz (#include) pliki nagłówkowe - ale one nie zawierają właściwego kodu. Dlatego musisz dolinkować bibliotekę dodając do kompilatora (a de-facto linkera schowanego w środku) opcję -lgnuplotpp.

No problem w tym, że gnuplot++ nie ma pliku make i musisz zrobić go ręcznie - popatrz na system Cmake, on powinien ułatwić ci robotę.
Paweł Kraszewski
~Arch/Void/Gentoo/FreeBSD/OpenBSD/Specjalizowane customy

cod3r

  • Gość
gnuplot API C++ - rysowanie wykresów
« Odpowiedź #4 dnia: 2011-05-03, 15:58:00 »
Ok, poszukałem trochę nowszych wersji API gnuplota i znalazłem. Są trzy pliki Makefile.am w trzech różnych floderach. Natomiast wywołując polecenie make -f Makefile.am dostaje odpowiedź brak obiektów. Zresztą, poniżej przedstawię zrzutkę z terminala, najpierw jakie pliki w jakich katalogach się znajdują, a dalej próbę wywołania polecenia make.

marcin@domlap:~/Pulpit/gnupplus$ ls
AUTHORS    ChangeLog     COPYING      NEWS    src
bootstrap  configure.ac  Makefile.am  README  THANKS
marcin@domlap:~/Pulpit/gnupplus$ cd src
marcin@domlap:~/Pulpit/gnupplus/src$ ls
drawable.cpp  gnuplot.cpp  gnupplus.hpp  Makefile.am  plots.cpp
except.cpp    gnupplus     layout.cpp    pipe.cpp     tests
marcin@domlap:~/Pulpit/gnupplus/src$ cd tests
marcin@domlap:~/Pulpit/gnupplus/src/tests$ ls
example.cpp  Makefile.am   simpleplot.cpp  test_environ.cc
layout0.cpp  realtime.cpp  testecho        test_environ.hh
marcin@domlap:~/Pulpit/gnupplus/src/tests$ cd ..
marcin@domlap:~/Pulpit/gnupplus/src$ cd gnupplus
marcin@domlap:~/Pulpit/gnupplus/src/gnupplus$ ls
drawable.hpp  except.hpp  gnuplot.hpp  layout.hpp  pipe.hpp  plots.hpp
marcin@domlap:~/Pulpit/gnupplus$ ls
AUTHORS    ChangeLog     COPYING      NEWS    src
bootstrap  configure.ac  Makefile.am  README  THANKS
marcin@domlap:~/Pulpit/gnupplus$ make
make: *** Nie podano obiektów i nie znaleziono makefile. Stop.
marcin@domlap:~/Pulpit/gnupplus$ make -f Makefile.am
make: *** Brak obiektów. Stop.
marcin@domlap:~/Pulpit/gnupplus$ cd src
marcin@domlap:~/Pulpit/gnupplus/src$ ls
drawable.cpp  gnuplot.cpp  gnupplus.hpp  Makefile.am  plots.cpp
except.cpp    gnupplus     layout.cpp    pipe.cpp     tests
marcin@domlap:~/Pulpit/gnupplus/src$ make -f Makefile.am
make: *** Brak obiektów. Stop.
marcin@domlap:~/Pulpit/gnupplus/src$ make
make: *** Nie podano obiektów i nie znaleziono makefile. Stop.
marcin@domlap:~/Pulpit/gnupplus/src$ cd tests
marcin@domlap:~/Pulpit/gnupplus/src/tests$ ls
example.cpp  Makefile.am   simpleplot.cpp  test_environ.cc
layout0.cpp  realtime.cpp  testecho        test_environ.hh
marcin@domlap:~/Pulpit/gnupplus/src/tests$ make -f Makefile.am
make: *** Brak obiektów. Stop.
No i najważniejsze, zawartości plików Makefile:
/gnupplus/Makefile.am
ACLOCAL_AMFLAGS = -I m4

EXTRA_DIST = bootstrap src/tests/testecho
SUBDIRS = src
#.PHONY : doc
#
#doc:
# cd doc; doxygen; cd ..
/gnupplus/src/Makefile.am
SUBDIRS = tests
AM_CPPFLAGS = -I./ -Wall -Werror
lib_LTLIBRARIES = libgnupplus.la

include_HEADERS = gnupplus.hpp

includetreedir = $(prefix)/include/gnupplus
includetree_HEADERS = gnupplus/except.hpp \\
                      gnupplus/gnuplot.hpp \\
                      gnupplus/pipe.hpp \\
                      gnupplus/plots.hpp \\
                      gnupplus/layout.hpp \\
                      gnupplus/drawable.hpp

libgnupplus_la_SOURCES = $(include_HEADERS) \\
                         $(includetreedir_HEADERS) \\
                         except.cpp \\
                         gnuplot.cpp \\
                         pipe.cpp \\
                         plots.cpp \\
                         layout.cpp \\
                         drawable.cpp
/gnupplus/src/tests/Makefile.am
AM_CPPFLAGS = -I$(top_srcdir)/src/ -I./ -Wall -Werror -D_GNU_SOURCE

check_PROGRAMS = example simpleplot layout0 realtime

TESTS = $(check_PROGRAMS)
AM_LDFLAGS = -L$(top_srcdir)/src/ -L./ -L../
LDADD = -lgnupplus

example_SOURCES = example.cpp test_environ.cc test_environ.hh
simpleplot_SOURCES = simpleplot.cpp test_environ.cc test_environ.hh
layout0_SOURCES = layout0.cpp test_environ.cc test_environ.hh
realtime_SOURCES = realtime.cpp test_environ.cc test_environ.hh
Prosiłbym Cię byś rzucił na to okiem, bo szczerze mówiąc wcześniej nie używałem plików Makefile i jakby uczę się dopiero teraz tego.

Offline Paweł Kraszewski

  • Administrator
  • Guru
  • *****
  • Wiadomości: 3066
  • Lenistwo jest matką potrzeby = babcią wynalazku
    • Zobacz profil
gnuplot API C++ - rysowanie wykresów
« Odpowiedź #5 dnia: 2011-05-03, 20:43:01 »
Pliki .am to nie właściwe pliki robocze a szablony wejściowe dla programu AUTOMAKE, pliki .ac to szablony dla programu AUTOCONF.

PIxOKO AUTOCONF na podstawie pliku .ac generuje plik configure. Uruchomienie ./configure na podstawie pliku .am generuje dopiero właściwy plik Makefile. I teraz dopiero działa make.

1. Generujesz plik ./configure wywołując autoreconf --install (może być potrzeba założenia katalogu m4)
2. Uruchamiasz plik configure wywołując ./configure --prefix="/usr/local".
3. Uruchamiasz program make.
4. Instalujesz uruchamiając jako administrator make install.

Biblioteka nazywa się libgnupplus.a, linkujesz ją parametrel -lgnupplus (to jest MINUS+MAŁE L)
Paweł Kraszewski
~Arch/Void/Gentoo/FreeBSD/OpenBSD/Specjalizowane customy

cod3r

  • Gość
gnuplot API C++ - rysowanie wykresów
« Odpowiedź #6 dnia: 2011-05-03, 21:18:49 »
Bardzo dziękuję za fachową pomoc!