Tworzenie bibliotek

problemy z funkcjonowaniem bibliotek, komponentów itp.

Tworzenie bibliotek

Nowy postprzez GoldWolf » środa, 30 września 2009, 20:06

Zastanawiam się nad jedną kwestią. Tworzeni sobie projekt i tworze do niego własne biblioteki.
Załóżmy pierwsze biblioteka będzie ściągać stronę, druga usuwać z niej tagi HTML. Wszystkie będą korzystać ze biblioteki string.
biblioteka 2:
#ifndef bibliotekaHTML_hpp
#define bibliotekaHTML_hpp
#include <string>

void UsuwajTagi(std::string const lancuch);

#endif

biblioteka 1:
#ifndef CzytajURL_hpp
#define CzytajURL_hpp
#include <string>

void CzytajURL(std::string &lancuch);

#endif

Plik program.cpp:
#include <vcl.h>
#pragma hdrstop
#include "CzytajURL.hpp"
#include "bibliotekaHTML_hpp"

Pytanie czy jest jakiś problem w tym, iż obie zawierają podłączenie biblioteki #include <string>?
Tylko dwie rzeczy są nieskończone: wszechświat oraz ludzka głupota, choć nie jestem pewien co do tej pierwszej. - Albert Einstein

Błędów nie popełnia ten, kto nic nie robi. - Theodore Roosevelt
Avatar użytkownika
GoldWolf
Homos antropiczny
Homos antropiczny
 
Posty: 116
Dołączył(a): piątek, 16 stycznia 2009, 18:42
Podziękował : 8
Otrzymał podziękowań: 0
System operacyjny: Siódemka Profesjonalna
Kompilator: Microsoft Visual Studio 2010
Version 10.0.30319.1
Gadu Gadu: 0
    NieznanyNieznana

Re: Tworzenie bibliotek

Nowy postprzez Cyfrowy Baron » środa, 30 września 2009, 20:59

Dlaczego wg. Ciebie miałoby to stanowić problem...?
Rzecz w tym, że one nie łączą się ze sobą poprzez program.cpp (mówiąć prościej - nic o sobie nie wiedzą) więc obie potrzebują biblioteki <string>, gdyż nie mogą się nią ze sobą wymieniać.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    NieznanyNieznana

Re: Tworzenie bibliotek

Nowy postprzez GoldWolf » sobota, 3 października 2009, 20:39

Nie wiem skąd mi to przyszło do głowy, pewnie to gdzieś wyczytałem. Jednak wszystko się wydaje być logiczne. Po prostu zastawiałem się czy jakoś można wyeliminować kilkukrotne dodawanie tych samych bibliotek, linkując własne biblioteki.

A jak poradzić sobie z napisaniem biblioteki, która musi skorzystać z pliku nagłówkowego aplikacji.
Załóżmy mam projekt G.cpp(i automatycznie G.h), a biblioteka mysi mieć dostęp do G.h. Dokładnie do komponentów, które znajdują się na Formie. Z tym, że ja nie wiem jak się będą nazywać plik G.h. Czy jest jakieś rozwiązanie tego problemu?
Tylko dwie rzeczy są nieskończone: wszechświat oraz ludzka głupota, choć nie jestem pewien co do tej pierwszej. - Albert Einstein

Błędów nie popełnia ten, kto nic nie robi. - Theodore Roosevelt
Avatar użytkownika
GoldWolf
Homos antropiczny
Homos antropiczny
 
Posty: 116
Dołączył(a): piątek, 16 stycznia 2009, 18:42
Podziękował : 8
Otrzymał podziękowań: 0
System operacyjny: Siódemka Profesjonalna
Kompilator: Microsoft Visual Studio 2010
Version 10.0.30319.1
Gadu Gadu: 0
    NieznanyNieznana

Re: Tworzenie bibliotek

Nowy postprzez polymorphism » sobota, 3 października 2009, 22:18

Dante napisał(a):A jak poradzić sobie z napisaniem biblioteki, która musi skorzystać z pliku nagłówkowego aplikacji.

W tym przypadku chyba trudno mówić o bibliotece, jest to raczej części aplikacji.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    NieznanyNieznana

Re: Tworzenie bibliotek

Nowy postprzez Cyfrowy Baron » sobota, 3 października 2009, 23:18

Biblioteka to plik, który może być wykorzystywany wielokrotnie w różnych programach. Zawiera zbiór funkcji, metod, klas, itp... które mogą, ale nie muszą być wykorzystywane w aplikacji, czyli tworzysz bibliotekę niejako na wyrost, nie na potrzeby programu, czyli nie możesz w niej umieścić odwołania do pliku nagłówkowego aplikacji.

Problem da się jednak rozwiązać.

Tworzysz sobie bibliotekę, potem gdy tworzysz program kopiujesz pliki biblioteki do katalogu programu, dodajesz do projektu i modyfikujesz zawartość biblioteki tak by prawidłowo współpracowała z projektem,

Jest to mało praktyczne rozwiązanie, ale sam je czasami stosuję. Przydaje się gdy w swoich programach często korzystasz z tych samych funkcji, metod, klas, itp...

Taką bibliotekę możesz stworzyć jednak tylko na własne potrzeby, gdyż inni mogli by mieć problemy z jej wykorzystaniem, no i powinieneś dokładnie ją opisać, żebyś wiedział jaki jest mechanizm działania tej biblioteki, gdy będziesz chciał z niej skorzystać po jakimś czasie.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    NieznanyNieznana

Re: Tworzenie bibliotek

Nowy postprzez GoldWolf » niedziela, 4 października 2009, 09:50

Tworzysz sobie bibliotekę, potem gdy tworzysz program kopiujesz pliki biblioteki do katalogu programu, dodajesz do projektu i modyfikujesz zawartość biblioteki tak by prawidłowo współpracowała z projektem,
Tak przypuszczałem, jednak za wiele jest nie wiadomych by można było wprowadzić jakieś uniwersalne rozwiązanie. Nie wiem przecież jak będzie nazwa TForm, oraz jak będa nazywały się pliki.
Ale to wystarczy dobrze opisać i poprawa w dwóch miejscach kodu.
Tylko dwie rzeczy są nieskończone: wszechświat oraz ludzka głupota, choć nie jestem pewien co do tej pierwszej. - Albert Einstein

Błędów nie popełnia ten, kto nic nie robi. - Theodore Roosevelt
Avatar użytkownika
GoldWolf
Homos antropiczny
Homos antropiczny
 
Posty: 116
Dołączył(a): piątek, 16 stycznia 2009, 18:42
Podziękował : 8
Otrzymał podziękowań: 0
System operacyjny: Siódemka Profesjonalna
Kompilator: Microsoft Visual Studio 2010
Version 10.0.30319.1
Gadu Gadu: 0
    NieznanyNieznana

Re: Tworzenie bibliotek

Nowy postprzez Cyfrowy Baron » niedziela, 4 października 2009, 10:28

Nazwy obiektów na formularzach aplikacji jak i sama nazwa aplikacji są nieistotne, możesz wszak wykorzystywać wskaźniki na obiekty, wystarczy odpowiednio skonstruować funkcję, np:

Biblioteka Unit2.h
Kod: Zaznacz cały
//---------------------------------------------------------------------------

#include <SysUtils.hpp>
#include <Classes.hpp>
#include <Controls.hpp>
#include <ExtCtrls.hpp>

//---------------------------------------------------------------------------
void __fastcall Funkcja(TForm *Okno, TColor kolor)
{
Okno->Color = kolor;
}


Teraz w aplikacji wystarczy:
Kod: Zaznacz cały
#include "Unit1.h"
#include "Unit2.h" // dołączanie biblioteki
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
Funkcja(this, clRed);
}
//---------------------------------------------------------------------------


Przy takiej konstrukcji funkcji biblioteka nie musi nic wiedzieć o formularzu.

Gorzej przedstawia się sytuacja, gdy chcesz się w bibliotece odwoływać do konkretnego obiektu na formularzu, gdyż biblioteka nie będzie nic o takim obiekcie wiedziała, ale może zakładać jego istnienie, czyli funkcja może wyglądać tak:

Biblioteka Unit2.h
Kod: Zaznacz cały
void __fastcall Funkcja(TPanel *Panel, TColor kolor)
{
Panel->Color = kolor;
}


W aplikacji:
Kod: Zaznacz cały
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
Funkcja(Panel1, clRed);
}
//---------------------------------------------------------------------------


Jak widzisz poprzez argumenty funkcji biblioteki możesz sterować dowolnym obiektem na formularzu, wystarczy, że biblioteka zakłada istnienie obiektu.
Zwróć uwagę na komponenty, przecież tworząc komponent nie tworzysz go dla konkretnej aplikacji, lecz dla aplikacji.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    NieznanyNieznana

Re: Tworzenie bibliotek

Nowy postprzez GoldWolf » niedziela, 18 października 2009, 10:28

Napotkałem na kłopot z klasą w tego typu budowie.
Kod: Zaznacz cały
#ifndef biblioteka_hpp
#define biblioteka_hpp
#include <string>
#include "grafik.h"
//prototypy funkcji
std::string F1(std::string const lancuch);
std::string F2(std::string const URL);
void F3(std::string &lancuch);
void F4(std::string &lancuch);
//Klasa Wątek ----------------------------------------------------
class Watek : public TThread{
   //WAŻNE BY ZMIENIĆ NAZWĘ TForm NA TAKĄ JAKA JEST U CIEBIE W PROJEKCIE
   TForm4 *tForm;

protected:
   void __fastcall Synchro(void);
   void __fastcall Execute(void);

public:
   // __fastcall myThread(TForm1 *Form);
   //WAŻNE BY ZMIENIĆ NAZWĘ TForm NA TAKĄ JAKA JEST U CIEBIE W PROJEKCIE
   Watek(TForm4 *_form):TThread(true), tForm(_form){}
//   std::string Url, stronaWWW;
};
#endif
No i plik:
Kod: Zaznacz cały
#include "bibliotekaHTML.hpp"
//Metoda synchronizacji dla Wątku ------------------------
void __fastcall Watek::Synchro(void){
int i = 0;
if (i == 0) {
    for (i = 0; i <= 10; i++) {
       i++;
       tForm->Memo1->Lines->Add(i);
    }
}
tForm->stronaWWW = F1(F2(tForm->Url));
F3(tForm->stronaWWW);
}
//Metody----Wątek -----------------------------------------
void __fastcall Watek::Execute(void){
int i = 0;
if (i == 0) {
    for (i = 0; i <= 10; i++) {
       i++;
       tForm->Memo1->Lines->Add(i);
    }
}

Synchronize(&Synchro);
/* while(1)
  Synchronize(&synchronizuj);*/
}
Pętle w metodach stworzyłem po to by sprawdzić czy te metody działają. No i właśnie nie działają. W pliku tym znajdują się też wszystkie funkcje ale ich nie umieszczałem by łatwiej przedstawić problem.
Ostatni plik:
Kod: Zaznacz cały
//---------------------------------------------------------------------------
//grafik cpp
#include <vcl.h>
#pragma hdrstop
//#include "grafik.h"
#include <biblioteka.hpp>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm4 *Form4;
Watek* watek1;
//---------------------------------------------------------------------------
__fastcall TForm4::TForm4(TComponent* Owner)
   : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm4::Button1Click(TObject *Sender)
{
  std::string Url = "http://programowanie.cal.pl/forum/index.php", stronaWWW;
  watek1 = new Watek(Form4);
  Url = "http://biznes.onet.pl/gm-sprzedal-hummera-chinczykom,18561,3042137,1,news-detal";
//Url = "http://biznes.onet.pl/gm-sprzedal-hummera-chinczykom,18561,3042137,1,news-detal";
//Url = "http://www.bet-at-home.com/odd.aspx?action=toggleEventGroup&SportID=1&EventGroupID=222";

   watek1->Resume();
   Memo1->Text = UTF8Decode(stronaWWW.c_str());
   watek1->Suspend();
delete watek1;
}
W Memo1 nic nie ma. Dałem Breakpoint w obu metodach klasy i kompilator w ogóle nie wchodzi do tych metod. Tak jakby metod klas nie było(nie wykonywały się).

Trochę eksperymentowałem i gdy do kodu Buttona dołożę dwie linijki, przed watek1->Resume();:
Kod: Zaznacz cały
tForm->stronaWWW = F1(F2(Url));
F3(stronaWWW);
To metody się wykonają, więc nie wiem co się stało. Dlaczego by dobrze zadziałał wątek muszę najpierw wykonać dwie funkcje, które to właśnie wątek powinien w sobie wykonać?

Druga pytanie o sposób podłączenia biblioteka.hpp. Wydawało mi się że powinno być "biblioteka.hpp", a ja musiałem zmienić na <biblioteka.hpp>, a przecież biblioteka ta znajduje się w folderze z projektem? Gdy ją podłączę pierwszym sposobem mam błędy.
blad.jpg
Nie masz wystarczających uprawnień, aby zobaczyć pliki załączone do tego postu.
Tylko dwie rzeczy są nieskończone: wszechświat oraz ludzka głupota, choć nie jestem pewien co do tej pierwszej. - Albert Einstein

Błędów nie popełnia ten, kto nic nie robi. - Theodore Roosevelt
Avatar użytkownika
GoldWolf
Homos antropiczny
Homos antropiczny
 
Posty: 116
Dołączył(a): piątek, 16 stycznia 2009, 18:42
Podziękował : 8
Otrzymał podziękowań: 0
System operacyjny: Siódemka Profesjonalna
Kompilator: Microsoft Visual Studio 2010
Version 10.0.30319.1
Gadu Gadu: 0
    NieznanyNieznana

Re: Tworzenie bibliotek

Nowy postprzez Witold » niedziela, 18 października 2009, 12:56

Dante napisał(a):
Kod: Zaznacz cały
   watek1->Resume();
   Memo1->Text = UTF8Decode(stronaWWW.c_str());
   watek1->Suspend();
delete watek1;
}
W Memo1 nic nie ma. Dałem Breakpoint w obu metodach klasy i kompilator w ogóle nie wchodzi do tych metod. Tak jakby metod klas nie było(nie wykonywały się).


Skąd wiesz że wątek zdążył się wykonać, nim go zawiesisz (watek1->Suspend();)
Wydaje mi się że dajesz mu na działanie tyle czasu ile wykonuje się Memo1->Text = UTF8Decode(stronaWWW.c_str());

Dante napisał(a):Trochę eksperymentowałem i gdy do kodu Buttona dołożę dwie linijki, przed watek1->Resume();:
Kod: Zaznacz cały
tForm->stronaWWW = F1(F2(Url));
F3(stronaWWW);
To metody się wykonają, więc nie wiem co się stało. Dlaczego by dobrze zadziałał wątek muszę najpierw wykonać dwie funkcje, które to właśnie wątek powinien w sobie wykonać?


Teraz ma pewnie na wykonanie wątku tyle czasu ile trwa wykonanie tych 3 funkcji na głównym wątku, widać tyle starcza. Chcesz "poczekać", to poczytaj o TThread::WaitFor;

Za ten post autor Witold otrzymał podziękowanie od:
GoldWolf
Avatar użytkownika
Witold
Konstrukcjonista
Konstrukcjonista
 
Posty: 223
Dołączył(a): piątek, 29 sierpnia 2008, 10:53
Podziękował : 1
Otrzymał podziękowań: 14
Kompilator: bcb6, Turbo C++ Explorer
    NieznanyNieznana

Re: Tworzenie bibliotek

Nowy postprzez GoldWolf » niedziela, 18 października 2009, 14:26

Nie wiedziałem, że tak to działa.
Kod: Zaznacz cały
   watek1->Resume();
   watek1->WaitFor();
    Memo1->Text = UTF8Decode(stronaWWW.c_str());
   //   watek1->Suspend();
   delete watek1;

Więc zostaje tylko pytanie o podłączenie biblioteki.
Tylko dwie rzeczy są nieskończone: wszechświat oraz ludzka głupota, choć nie jestem pewien co do tej pierwszej. - Albert Einstein

Błędów nie popełnia ten, kto nic nie robi. - Theodore Roosevelt
Avatar użytkownika
GoldWolf
Homos antropiczny
Homos antropiczny
 
Posty: 116
Dołączył(a): piątek, 16 stycznia 2009, 18:42
Podziękował : 8
Otrzymał podziękowań: 0
System operacyjny: Siódemka Profesjonalna
Kompilator: Microsoft Visual Studio 2010
Version 10.0.30319.1
Gadu Gadu: 0
    NieznanyNieznana

Re: Tworzenie bibliotek

Nowy postprzez Witold » niedziela, 18 października 2009, 15:23

Dante napisał(a):Nie wiedziałem, że tak to działa.


W mojej podpowiedzi chodziło abyś nie wstrzymywał wątku, nim on nie zrobi tego co ma zrobić - to czekanie było tylko po to.
Hmm, jeśli będziesz na głównym wątku czekał aż wątek poboczny zakończy działanie, to nie bardzo wiem do czego Ci ten wątek poboczny?
Jeszcze ponazywałeś tak zrozumiale funkcje F1, F2, F3, że łatwo się połapać o co chodzi ;) .
Avatar użytkownika
Witold
Konstrukcjonista
Konstrukcjonista
 
Posty: 223
Dołączył(a): piątek, 29 sierpnia 2008, 10:53
Podziękował : 1
Otrzymał podziękowań: 14
Kompilator: bcb6, Turbo C++ Explorer
    NieznanyNieznana

Re: Tworzenie bibliotek

Nowy postprzez GoldWolf » niedziela, 18 października 2009, 15:25

Jeśli chodzi o funkcje to nie chciałem na razie odkrywać kart, chodziło tylko o pomoc z wątkiem.
Tylko dwie rzeczy są nieskończone: wszechświat oraz ludzka głupota, choć nie jestem pewien co do tej pierwszej. - Albert Einstein

Błędów nie popełnia ten, kto nic nie robi. - Theodore Roosevelt
Avatar użytkownika
GoldWolf
Homos antropiczny
Homos antropiczny
 
Posty: 116
Dołączył(a): piątek, 16 stycznia 2009, 18:42
Podziękował : 8
Otrzymał podziękowań: 0
System operacyjny: Siódemka Profesjonalna
Kompilator: Microsoft Visual Studio 2010
Version 10.0.30319.1
Gadu Gadu: 0
    NieznanyNieznana

Re: Tworzenie bibliotek

Nowy postprzez Witold » niedziela, 18 października 2009, 16:14

Może spróbuj wykonywać całą robotę w wątku pobocznym (ściąganie strony, UTF8Decode, itd), gdy wątek poboczny zrobi swoją robotę, niech zawiadomi wątek główny że skończył, ja bym spróbował prze wysłanie komunikatu SendMessage jak tu (to nie c++, ale może być pomocne, jak nie może wyszukasz coś lepszego):

http://edu.i-lo.tarnow.pl/inf/prg/002_winasm/0016.php

można by też wykorzystać: TThread::OnTerminate
Ostatnio edytowano niedziela, 18 października 2009, 16:32 przez Witold, łącznie edytowano 1 raz
Avatar użytkownika
Witold
Konstrukcjonista
Konstrukcjonista
 
Posty: 223
Dołączył(a): piątek, 29 sierpnia 2008, 10:53
Podziękował : 1
Otrzymał podziękowań: 14
Kompilator: bcb6, Turbo C++ Explorer
    NieznanyNieznana

Re: Tworzenie bibliotek

Nowy postprzez GoldWolf » niedziela, 18 października 2009, 16:29

Tu masz racę, z tym to już sobie poradzę. Myślałem, że użycie watek->resume(); działa jak wywołanie funkcji. Co samo przez sie było by bezsensu.
Tylko dwie rzeczy są nieskończone: wszechświat oraz ludzka głupota, choć nie jestem pewien co do tej pierwszej. - Albert Einstein

Błędów nie popełnia ten, kto nic nie robi. - Theodore Roosevelt
Avatar użytkownika
GoldWolf
Homos antropiczny
Homos antropiczny
 
Posty: 116
Dołączył(a): piątek, 16 stycznia 2009, 18:42
Podziękował : 8
Otrzymał podziękowań: 0
System operacyjny: Siódemka Profesjonalna
Kompilator: Microsoft Visual Studio 2010
Version 10.0.30319.1
Gadu Gadu: 0
    NieznanyNieznana


Powrót do Biblioteki i komponenty

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 4 gości

cron