Bonjour,
j'avais pour dessein de faire une classe permettant de stocker et récupérer des données sous forme d'une pile FIFO ; cette classe a pour particularité de jouer un rôle de synchronisation entre des threads (par défaut un appel à la fonction "get" fige jusqu'à ce que des données soient disponibles).
Pour faire quelque peu générique, j'utilise des templates et là le bât blesse :
si tout le code de la classe (celui de WaitingList.hpp et WaitingList.cpp) est dans le fichier main.cpp tout compile à merveille (même pas encore testé d'ailleurs), mais si la classe à droit à ses fichiers hpp et cpp, j'ai droit à un :
etc
Code : Sélectionner tout - Visualiser dans une fenêtre à part undefined reference to `WaitingList<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >::WaitingList()'
Sniff. Quelqu'un aurait-il une idée ? (je suis à peu près sûr que c'est une erreur évidente ....)
P.S. : voici la ligne de compilation :
Voici le main (dans main.cpp) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 g++ -g -Wall -c -ansi -Wno-deprecated toto/src/main.cpp -o toto2 g++ -g -Wall -c -ansi -Wno-deprecated toto/src/WaitingList/WaitingList.cpp -o toto1 g++ -g -Wall -ansi -Wno-deprecated toto1 toto2 -o toto.exe
voici la classe WaitingList (dans WaitingList.hpp) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 int main (void) { string toto; WaitingList <string> titi; titi.put("Test\n"); //cout << titi.take() << endl; return 0; }
voici la classe WaitingList (dans WaitingList.cpp) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 #ifndef WAITING_LIST_H #define WAITING_LIST_H #include <semaphore.h> #include <errno.h> #include <assert.h> #include <list> using namespace std; template <class T> class WaitingList{ private: sem_t semaphore; list <T> list; timespec timeout; public: WaitingList(); T take(bool *timedOutOrError, int timeout = 0); void put(const T &value); }; #endif
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64 #include "WaitingList.hpp" /*prend un temps en milliseconde et convertit X == variable de type timespec Y == durée en milliseconde */ #define TIMESPEC(X, Y) X.tv_sec = Y/1000;X.tv_nsec = (long int) ((((long long)Y)*1000)%1000000); #define WAIT(X) sem_wait(X) #define TIMED_WAIT(X, Y) sem_timedwait(X, Y) #define SIGNAL(X) sem_post(X) #define WAIT_AND_SIGNAL(X) sem_wait(X);sem_post(X) #define SEMAPHORE(X, Y) sem_init(X, 0, Y) template <class T> WaitingList<T>::WaitingList() { int retour = SEMAPHORE(&semaphore, 0); assert(retour == 0); } template <class T> T WaitingList<T>::take(bool *timedOutOrError, int timeout) { T retour; int error; assert(timeout>=0); if (timedOutOrError) *timedOutOrError = false; if (timeout) { TIMESPEC(this->timeout, timeout); error = TIMED_WAIT(&semaphore, this->timeout); if ((error != ETIMEDOUT) && (error != EINTR)) { retour = list.back(); list.pop_back(); return retour; } else { if (timedOutOrError) *timedOutOrError = true; return T(); } }else { error = WAIT(&semaphore); if (error == 0) { retour = list.back(); list.pop_back(); return retour; } else { if (timedOutOrError) *timedOutOrError = true; return T(); } } } template <class T> void WaitingList<T>::put(const T &value) { list.push_front(value); SIGNAL(&semaphore); }
Partager