Hypercell ein ] Hypercell aus ] Zeige Navigation ] Verstecke Navigation ]
c++.de  
   
Forentreff 2012     
Bücher-Shop mit Amazon (Buchkategorien)C++ : Referenzen zu C++ : C++ Builder : Visual C++ : C# : Java : Spieleprogrammierung : Systemprogrammierung Linux : Software-Entwicklung : .NET : Compilertechnik : Algorithmen & Datenstrukturen : Objektorientierung : Entwurfsmuster : UML : eXtreme Programming : Scrum : Projektmanagement : Software-Testing : Datenbanken : Tom DeMarco : Dilbert : User Friendly
C/C++ Forum :: VCL (C++ Builder) ::  Thread-Problem  
Gehen Sie zu Seite 1, 2  Weiter
  Zeige alle Beiträge auf einer Seite
Auf Beitrag antworten
Autor Nachricht
Wiesel666
Unregistrierter




Beitrag Wiesel666 Unregistrierter 22:40:36 20.01.2010   Titel:   Thread-Problem            Zitieren

Hi


Ich habe ein Problem mit Threads. In den Threads will ich eine Funktion zum synchonisieren aufrufen, der aber noch einen String übergeben werden soll:

C/C++ Code:
void __fastcall FindBlogs::updatetext(AnsiString code)
{
  Form1->Memo1->Text = code;
}
C/C++ Code:
void __fastcall FindBlogs::updatetext(AnsiString code)
{
Form1->Memo1->Text = code;
}
C/C++ Code:
void __fastcall FindBlogs::updatetext(AnsiString code)
{
  Form1->Memo1->Text = code;
}


C/C++ Code:
AnsiString meinString= "irgendwas";
Synchronize(&updatetext(blub));
C/C++ Code:
AnsiString meinString= "irgendwas";
Synchronize(&updatetext(blub));
C/C++ Code:
AnsiString meinString= "irgendwas";
Synchronize(&updatetext(blub));

Ich bekomme diesen Fehler:

Zitat:
[C++ Error] Unit2.cpp(64): E2109 Not an allowed type


Weiß jemand was ich falsch mache ?
Killer-Kobold
Mitglied

Benutzerprofil
Anmeldungsdatum: 16.03.2009
Beiträge: 180
Beitrag Killer-Kobold Mitglied 23:40:08 20.01.2010   Titel:              Zitieren

Ja, das ist eine nervige Sache... Man kann keine Parameter übergeben. Punkt.

Mach den AnsiString zu einer Membervariable des Threads, damit er in beiden Funktionen zur Verfügung steht.

Gruß KK
audacia
Mitglied

Benutzerprofil
Anmeldungsdatum: 05.02.2005
Beiträge: 3891
Beitrag audacia Mitglied 02:48:52 21.01.2010   Titel:              Zitieren

In Delphi gibt es dafür praktischerweise anonyme Methoden, dort sähe das etwa so aus:
Code:
type
  meinString: String;
begin
  Synchronize (procedure
    begin
      UpdateText (meinString)
    end);
Code:
type
meinString: String;
begin
Synchronize (procedure
begin
UpdateText (meinString)
end);
Code:
type
  meinString: String;
begin
  Synchronize (procedure
    begin
      UpdateText (meinString)
    end);


In C++ gibt es das leider (noch) nicht; einstweilen kannst du aber ein Funktionsobjekt zu solchem Zwecke benutzen. Man könnte sich sogar eine Wrapperklasse schreiben, die die Parameterübergabe einigermaßen annehmlich macht (das wäre mal wieder ein Fall für Variadic Templates - leider unterstützt BCC die noch nicht). Zufällig hatte ich gerade Lust dazu:

C/C++ Code:
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
class TCppThread;

namespace detail
{

enum NoType { ntNoVal };
enum SyncType
{
    stSynchronized,
    stQueued,
};

template <typename T>
    struct RefWrapper
{
    T val;
    RefWrapper (void) {}
    RefWrapper (const T& _val) : val (_val) {}
    operator T (void) { return val; }
};
template <typename T>
    struct RefWrapper <T&>
{
    T* val;
    RefWrapper (void) {}
    RefWrapper (T& _val) : val (&_val) {}
    operator T& (void) { return *val; }
};

template <typename T, typename FuncObjT, typename R,
          typename T1 = NoType, typename T2 = NoType, typename T3 = NoType>
    struct SyncExchangeData
{
private:
    T* self;
    FuncObjT funcObj;
    R r;
    RefWrapper <T1> p1;
    RefWrapper <T2> p2;
    RefWrapper <T3> p3;

    T* cast (TCppThread* _self) { return &dynamic_cast <T&> (*_self); }

public:

    SyncExchangeData (TCppThread* _self, FuncObjT _funcObj)
     : self (cast (_self)), funcObj (_funcObj)
    {}
    SyncExchangeData (TCppThread* _self, FuncObjT _funcObj, T1 _p1)
     : self (cast (_self)), funcObj (_funcObj), p1 (_p1)
    {}
    SyncExchangeData (TCppThread* _self, FuncObjT _funcObj, T1 _p1, T2 _p2)
     : self (cast (_self)), funcObj (_funcObj), p1 (_p1), p2 (_p2)
    {}
    SyncExchangeData (TCppThread* _self, FuncObjT _funcObj, T1 _p1, T2 _p2, T3 _p3)
     : self (cast (_self)), funcObj (_funcObj), p1 (_p1), p2 (_p2), p3 (_p3)
    {}

    template <typename>
        void __fastcall doSyncCall0 (void) { r = (self->*funcObj) (); }
    template <typename>
        void __fastcall doSyncCall1 (void) { r = (self->*funcObj) (p1); }
    template <typename>
        void __fastcall doSyncCall2 (void) { r = (self->*funcObj) (p1, p2); }
    template <typename>
        void __fastcall doSyncCall3 (void) { r = (self->*funcObj) (p1, p2, p3); }

    R getResult (void) { return r; }
};

template <typename T, typename FuncObjT,
          typename T1 = NoType, typename T2 = NoType, typename T3 = NoType>
    struct SyncExchangeData <T, FuncObjT, void, T1, T2, T3>
{
private:
    T* self;
    FuncObjT funcObj;
    RefWrapper <T1> p1;
    RefWrapper <T2> p2;
    RefWrapper <T3> p3;

    T* cast (TCppThread* _self) { return &dynamic_cast <T&> (*_self); }

public:

    SyncExchangeData (TCppThread* _self, FuncObjT _funcObj)
     : self (cast (_self)), funcObj (_funcObj)
    {}
    SyncExchangeData (TCppThread* _self, FuncObjT _funcObj, T1 _p1)
     : self (cast (_self)), funcObj (_funcObj), p1 (_p1)
    {}
    SyncExchangeData (TCppThread* _self, FuncObjT _funcObj, T1 _p1, T2 _p2)
     : self (cast (_self)), funcObj (_funcObj), p1 (_p1), p2 (_p2)
    {}
    SyncExchangeData (TCppThread* _self, FuncObjT _funcObj, T1 _p1, T2 _p2, T3 _p3)
     : self (cast (_self)), funcObj (_funcObj), p1 (_p1), p2 (_p2), p3 (_p3)
    {}

    template <typename>
        void __fastcall doSyncCall0 (void) { (self->*funcObj) (); }
    template <typename>
        void __fastcall doSyncCall1 (void) { (self->*funcObj) (p1); }
    template <typename>
        void __fastcall doSyncCall2 (void) { (self->*funcObj) (p1, p2); }
    template <typename>
        void __fastcall doSyncCall3 (void) { (self->*funcObj) (p1, p2, p3); }

    void getResult (void) { }
};

} // namespace detail


class TCppThread : public TThread
{
protected:
    template <typename T, typename R>
        R SynchronizedCall (R (T::* func) (void))
    {
#ifdef
__CODEGEARC__
        static_assert (__is_base_of (TCppThread, T), "T is not a base of TCppThread");
#endif
        typedef
R (T::* FuncObjT) (void);
        detail::SyncExchangeData <T, FuncObjT, R> sed (this, func);
        Synchronize (sed.doSyncCall0 <R>);
        return sed.getResult ();
    }
    template <typename T, typename R,
            typename T1, typename TT1>
        R SynchronizedCall (R (T::* func) (T1), TT1 p1)
    {
#ifdef
__CODEGEARC__
        static_assert (__is_base_of (TCppThread, T), "T is not a base of TCppThread");
#endif
        typedef
R (T::* FuncObjT) (T1);
        detail::SyncExchangeData <T, FuncObjT, R, T1> sed (this, func, p1);
        Synchronize (sed.doSyncCall1 <R>);
        return sed.getResult ();
    }
    template <typename T, typename R,
            typename T1, typename TT1,
            typename T2, typename TT2>
        R SynchronizedCall (R (T::* func) (T1, T2), TT1 p1, TT2 p2)
    {
#ifdef
__CODEGEARC__
        static_assert (__is_base_of (TCppThread, T), "T is not a base of TCppThread");
#endif
        typedef
R (T::* FuncObjT) (T1, T2);
        detail::SyncExchangeData <T, FuncObjT, R, T1, T2> sed (this, func, p1, p2);
        Synchronize (sed.doSyncCall2 <R>);
        return sed.getResult ();
    }
    template <typename T, typename R,
            typename T1, typename TT1,
            typename T2, typename TT2,
            typename T3, typename TT3>
        R SynchronizedCall (R (T::* func) (T1, T2, T3), TT1 p1, TT2 p2, TT3 p3)
    {
#ifdef
__CODEGEARC__
        static_assert (__is_base_of (TCppThread, T), "T is not a base of TCppThread");
#endif
        typedef
R (T::* FuncObjT) (T1, T2, T3);
        detail::SyncExchangeData <T, FuncObjT, R, T1, T2, T3> sed (this, func, p1, p2, p3);
        Synchronize (sed.doSyncCall3 <R>);
        return sed.getResult ();
    }

public:
    __fastcall TCppThread (bool CreateSuspended) : TThread (CreateSuspended) {}
};
C/C++ Code:
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
class TCppThread;

namespace detail
{

enum NoType { ntNoVal };
enum SyncType
{
stSynchronized,
stQueued,
};

template <typename T>
struct RefWrapper
{
T val;
RefWrapper (void) {}
RefWrapper (const T& _val) : val (_val) {}
operator T (void) { return val; }
};
template <typename T>
struct RefWrapper <T&>
{
T* val;
RefWrapper (void) {}
RefWrapper (T& _val) : val (&_val) {}
operator T& (void) { return *val; }
};

template <typename T, typename FuncObjT, typename R,
typename T1 = NoType, typename T2 = NoType, typename T3 = NoType>
struct SyncExchangeData
{
private:
T* self;
FuncObjT funcObj;
R r;
RefWrapper <T1> p1;
RefWrapper <T2> p2;
RefWrapper <T3> p3;

T* cast (TCppThread* _self) { return &dynamic_cast <T&> (*_self); }

public:

SyncExchangeData (TCppThread* _self, FuncObjT _funcObj)
: self (cast (_self)), funcObj (_funcObj)
{}
SyncExchangeData (TCppThread* _self, FuncObjT _funcObj, T1 _p1)
: self (cast (_self)), funcObj (_funcObj), p1 (_p1)
{}
SyncExchangeData (TCppThread* _self, FuncObjT _funcObj, T1 _p1, T2 _p2)
: self (cast (_self)), funcObj (_funcObj), p1 (_p1), p2 (_p2)
{}
SyncExchangeData (TCppThread* _self, FuncObjT _funcObj, T1 _p1, T2 _p2, T3 _p3)
: self (cast (_self)), funcObj (_funcObj), p1 (_p1), p2 (_p2), p3 (_p3)
{}

template <typename>
void __fastcall doSyncCall0 (void) { r = (self->*funcObj) (); }
template <typename>
void __fastcall doSyncCall1 (void) { r = (self->*funcObj) (p1); }
template <typename>
void __fastcall doSyncCall2 (void) { r = (self->*funcObj) (p1, p2); }
template <typename>
void __fastcall doSyncCall3 (void) { r = (self->*funcObj) (p1, p2, p3); }

R getResult (void) { return r; }
};

template <typename T, typename FuncObjT,
typename T1 = NoType, typename T2 = NoType, typename T3 = NoType>
struct SyncExchangeData <T, FuncObjT, void, T1, T2, T3>
{
private:
T* self;
FuncObjT funcObj;
RefWrapper <T1> p1;
RefWrapper <T2> p2;
RefWrapper <T3> p3;

T* cast (TCppThread* _self) { return &dynamic_cast <T&> (*_self); }

public:

SyncExchangeData (TCppThread* _self, FuncObjT _funcObj)
: self (cast (_self)), funcObj (_funcObj)
{}
SyncExchangeData (TCppThread* _self, FuncObjT _funcObj, T1 _p1)
: self (cast (_self)), funcObj (_funcObj), p1 (_p1)
{}
SyncExchangeData (TCppThread* _self, FuncObjT _funcObj, T1 _p1, T2 _p2)
: self (cast (_self)), funcObj (_funcObj), p1 (_p1), p2 (_p2)
{}
SyncExchangeData (TCppThread* _self, FuncObjT _funcObj, T1 _p1, T2 _p2, T3 _p3)
: self (cast (_self)), funcObj (_funcObj), p1 (_p1), p2 (_p2), p3 (_p3)
{}

template <typename>
void __fastcall doSyncCall0 (void) { (self->*funcObj) (); }
template <typename>
void __fastcall doSyncCall1 (void) { (self->*funcObj) (p1); }
template <typename>
void __fastcall doSyncCall2 (void) { (self->*funcObj) (p1, p2); }
template <typename>
void __fastcall doSyncCall3 (void) { (self->*funcObj) (p1, p2, p3); }

void getResult (void) { }
};

} // namespace detail


class TCppThread : public TThread
{
protected:
template <typename T, typename R>
R SynchronizedCall (R (T::* func) (void))
{
#ifdef
__CODEGEARC__
static_assert (__is_base_of (TCppThread, T), "T is not a base of TCppThread");
#endif
typedef
R (T::* FuncObjT) (void);
detail::SyncExchangeData <T, FuncObjT, R> sed (this, func);
Synchronize (sed.doSyncCall0 <R>);
return sed.getResult ();
}
template <typename T, typename R,
typename T1, typename TT1>
R SynchronizedCall (R (T::* func) (T1), TT1 p1)
{
#ifdef
__CODEGEARC__
static_assert (__is_base_of (TCppThread, T), "T is not a base of TCppThread");
#endif
typedef
R (T::* FuncObjT) (T1);
detail::SyncExchangeData <T, FuncObjT, R, T1> sed (this, func, p1);
Synchronize (sed.doSyncCall1 <R>);
return sed.getResult ();
}
template <typename T, typename R,
typename T1, typename TT1,
typename T2, typename TT2>
R SynchronizedCall (R (T::* func) (T1, T2), TT1 p1, TT2 p2)
{
#ifdef
__CODEGEARC__
static_assert (__is_base_of (TCppThread, T), "T is not a base of TCppThread");
#endif
typedef
R (T::* FuncObjT) (T1, T2);
detail::SyncExchangeData <T, FuncObjT, R, T1, T2> sed (this, func, p1, p2);
Synchronize (sed.doSyncCall2 <R>);
return sed.getResult ();
}
template <typename T, typename R,
typename T1, typename TT1,
typename T2, typename TT2,
typename T3, typename TT3>
R SynchronizedCall (R (T::* func) (T1, T2, T3), TT1 p1, TT2 p2, TT3 p3)
{
#ifdef
__CODEGEARC__
static_assert (__is_base_of (TCppThread, T), "T is not a base of TCppThread");
#endif
typedef
R (T::* FuncObjT) (T1, T2, T3);
detail::SyncExchangeData <T, FuncObjT, R, T1, T2, T3> sed (this, func, p1, p2, p3);
Synchronize (sed.doSyncCall3 <R>);
return sed.getResult ();
}

public:
__fastcall TCppThread (bool CreateSuspended) : TThread (CreateSuspended) {}
};
C/C++ Code:
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
class TCppThread;

namespace detail
{

enum NoType { ntNoVal };
enum SyncType
{
    stSynchronized,
    stQueued,
};

template <typename T>
    struct RefWrapper
{
    T val;
    RefWrapper (void) {}
    RefWrapper (const T& _val) : val (_val) {}
    operator T (void) { return val; }
};
template <typename T>
    struct RefWrapper <T&>
{
    T* val;
    RefWrapper (void) {}
    RefWrapper (T& _val) : val (&_val) {}
    operator T& (void) { return *val; }
};

template <typename T, typename FuncObjT, typename R,
          typename T1 = NoType, typename T2 = NoType, typename T3 = NoType>
    struct SyncExchangeData
{
private:
    T* self;
    FuncObjT funcObj;
    R r;
    RefWrapper <T1> p1;
    RefWrapper <T2> p2;
    RefWrapper <T3> p3;

    T* cast (TCppThread* _self) { return &dynamic_cast <T&> (*_self); }

public:

    SyncExchangeData (TCppThread* _self, FuncObjT _funcObj)
     : self (cast (_self)), funcObj (_funcObj)
    {}
    SyncExchangeData (TCppThread* _self, FuncObjT _funcObj, T1 _p1)
     : self (cast (_self)), funcObj (_funcObj), p1 (_p1)
    {}
    SyncExchangeData (TCppThread* _self, FuncObjT _funcObj, T1 _p1, T2 _p2)
     : self (cast (_self)), funcObj (_funcObj), p1 (_p1), p2 (_p2)
    {}
    SyncExchangeData (TCppThread* _self, FuncObjT _funcObj, T1 _p1, T2 _p2, T3 _p3)
     : self (cast (_self)), funcObj (_funcObj), p1 (_p1), p2 (_p2), p3 (_p3)
    {}

    template <typename>
        void __fastcall doSyncCall0 (void) { r = (self->*funcObj) (); }
    template <typename>
        void __fastcall doSyncCall1 (void) { r = (self->*funcObj) (p1); }
    template <typename>
        void __fastcall doSyncCall2 (void) { r = (self->*funcObj) (p1, p2); }
    template <typename>
        void __fastcall doSyncCall3 (void) { r = (self->*funcObj) (p1, p2, p3); }

    R getResult (void) { return r; }
};

template <typename T, typename FuncObjT,
          typename T1 = NoType, typename T2 = NoType, typename T3 = NoType>
    struct SyncExchangeData <T, FuncObjT, void, T1, T2, T3>
{
private:
    T* self;
    FuncObjT funcObj;
    RefWrapper <T1> p1;
    RefWrapper <T2> p2;
    RefWrapper <T3> p3;

    T* cast (TCppThread* _self) { return &dynamic_cast <T&> (*_self); }

public:

    SyncExchangeData (TCppThread* _self, FuncObjT _funcObj)
     : self (cast (_self)), funcObj (_funcObj)
    {}
    SyncExchangeData (TCppThread* _self, FuncObjT _funcObj, T1 _p1)
     : self (cast (_self)), funcObj (_funcObj), p1 (_p1)
    {}
    SyncExchangeData (TCppThread* _self, FuncObjT _funcObj, T1 _p1, T2 _p2)
     : self (cast (_self)), funcObj (_funcObj), p1 (_p1), p2 (_p2)
    {}
    SyncExchangeData (TCppThread* _self, FuncObjT _funcObj, T1 _p1, T2 _p2, T3 _p3)
     : self (cast (_self)), funcObj (_funcObj), p1 (_p1), p2 (_p2), p3 (_p3)
    {}

    template <typename>
        void __fastcall doSyncCall0 (void) { (self->*funcObj) (); }
    template <typename>
        void __fastcall doSyncCall1 (void) { (self->*funcObj) (p1); }
    template <typename>
        void __fastcall doSyncCall2 (void) { (self->*funcObj) (p1, p2); }
    template <typename>
        void __fastcall doSyncCall3 (void) { (self->*funcObj) (p1, p2, p3); }

    void getResult (void) { }
};

} // namespace detail


class TCppThread : public TThread
{
protected:
    template <typename T, typename R>
        R SynchronizedCall (R (T::* func) (void))
    {
#ifdef
__CODEGEARC__
        static_assert (__is_base_of (TCppThread, T), "T is not a base of TCppThread");
#endif
        typedef
R (T::* FuncObjT) (void);
        detail::SyncExchangeData <T, FuncObjT, R> sed (this, func);
        Synchronize (sed.doSyncCall0 <R>);
        return sed.getResult ();
    }
    template <typename T, typename R,
            typename T1, typename TT1>
        R SynchronizedCall (R (T::* func) (T1), TT1 p1)
    {
#ifdef
__CODEGEARC__
        static_assert (__is_base_of (TCppThread, T), "T is not a base of TCppThread");
#endif
        typedef
R (T::* FuncObjT) (T1);
        detail::SyncExchangeData <T, FuncObjT, R, T1> sed (this, func, p1);
        Synchronize (sed.doSyncCall1 <R>);
        return sed.getResult ();
    }
    template <typename T, typename R,
            typename T1, typename TT1,
            typename T2, typename TT2>
        R SynchronizedCall (R (T::* func) (T1, T2), TT1 p1, TT2 p2)
    {
#ifdef
__CODEGEARC__
        static_assert (__is_base_of (TCppThread, T), "T is not a base of TCppThread");
#endif
        typedef
R (T::* FuncObjT) (T1, T2);
        detail::SyncExchangeData <T, FuncObjT, R, T1, T2> sed (this, func, p1, p2);
        Synchronize (sed.doSyncCall2 <R>);
        return sed.getResult ();
    }
    template <typename T, typename R,
            typename T1, typename TT1,
            typename T2, typename TT2,
            typename T3, typename TT3>
        R SynchronizedCall (R (T::* func) (T1, T2, T3), TT1 p1, TT2 p2, TT3 p3)
    {
#ifdef
__CODEGEARC__
        static_assert (__is_base_of (TCppThread, T), "T is not a base of TCppThread");
#endif
        typedef
R (T::* FuncObjT) (T1, T2, T3);
        detail::SyncExchangeData <T, FuncObjT, R, T1, T2, T3> sed (this, func, p1, p2, p3);
        Synchronize (sed.doSyncCall3 <R>);
        return sed.getResult ();
    }

public:
    __fastcall TCppThread (bool CreateSuspended) : TThread (CreateSuspended) {}
};



Anwendung wie folgt:
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class TMyThread : public TCppThread
{
private:
    int foo (void) { return 42; }
    String bar (String s) { return "foo=" + s; }
    void baz (int i, String& s) { s = String (i); }

public:
    TMyThread (void) : TCppThread (false) {}

    void __fastcall Execute (void)
    {
        int fooResult = SynchronizedCall (&TMyThread::foo);
        String barResult = SynchronizedCall (&TMyThread::bar, "bar");
        String bazResult;
        SynchronizedCall (&TMyThread::baz, 42, static_cast <String&> (bazResult));
        assert (fooResult == 42);
        assert (barResult == "foo=bar");
        assert (bazResult == "42");
    }
};
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class TMyThread : public TCppThread
{
private:
int foo (void) { return 42; }
String bar (String s) { return "foo=" + s; }
void baz (int i, String& s) { s = String (i); }

public:
TMyThread (void) : TCppThread (false) {}

void __fastcall Execute (void)
{
int fooResult = SynchronizedCall (&TMyThread::foo);
String barResult = SynchronizedCall (&TMyThread::bar, "bar");
String bazResult;
SynchronizedCall (&TMyThread::baz, 42, static_cast <String&> (bazResult));
assert (fooResult == 42);
assert (barResult == "foo=bar");
assert (bazResult == "42");
}
};
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class TMyThread : public TCppThread
{
private:
    int foo (void) { return 42; }
    String bar (String s) { return "foo=" + s; }
    void baz (int i, String& s) { s = String (i); }

public:
    TMyThread (void) : TCppThread (false) {}

    void __fastcall Execute (void)
    {
        int fooResult = SynchronizedCall (&TMyThread::foo);
        String barResult = SynchronizedCall (&TMyThread::bar, "bar");
        String bazResult;
        SynchronizedCall (&TMyThread::baz, 42, static_cast <String&> (bazResult));
        assert (fooResult == 42);
        assert (barResult == "foo=bar");
        assert (bazResult == "42");
    }
};


Getestet mit C++Builder 2010, sollte aber auch mit früheren Versionen funktionieren.

_________________
"Hey, it compiles! Ship it!"
C++Builder Pages · Typsichere Format-Strings
Wiesel666
Unregistrierter




Beitrag Wiesel666 Unregistrierter 14:50:34 21.01.2010   Titel:              Zitieren

Das Programm schnurrt jetzt wie ein Kätzchen.
Wenn ich jedoch den Butten zum Thread-start drücke schmiert das Programm ab:

Unit1.cpp:

C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//---------------------------------------------------------------------------

#include
<vcl.h>
#pragma
hdrstop

#include
"Unit1.h"
#include
"Unit2.h"
#include
"Unit2.cpp"
//---------------------------------------------------------------------------
#pragma
package(smart_init)
#pragma
resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
   
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
  new FindBlogs(false);
}
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//---------------------------------------------------------------------------

#include
<vcl.h>
#pragma
hdrstop

#include
"Unit1.h"
#include
"Unit2.h"
#include
"Unit2.cpp"
//---------------------------------------------------------------------------
#pragma
package(smart_init)
#pragma
resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{

}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
new FindBlogs(false);
}
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//---------------------------------------------------------------------------

#include
<vcl.h>
#pragma
hdrstop

#include
"Unit1.h"
#include
"Unit2.h"
#include
"Unit2.cpp"
//---------------------------------------------------------------------------
#pragma
package(smart_init)
#pragma
resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
   
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
  new FindBlogs(false);
}




Unit2.Cpp:
C/C++ Code:
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
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
//---------------------------------------------------------------------------

#include
<vcl.h>
#pragma
hdrstop

#include
"Unit2.h"
#include
"Unit1.h"
#pragma
package(smart_init)

AnsiString puffer = "";
TStringList* text = new TStringList();  //<- Die globale Stringlist die nachher //noch in Unit 1.cpp gebraucht wird

//---------------------------------------------------------------------------


__fastcall FindBlogs::FindBlogs(bool CreateSuspended)
        : TThread(CreateSuspended)
{
   FreeOnTerminate;
}

void __fastcall FindBlogs::updatetext()
{

}

//---------------------------------------------------------------------------
void __fastcall FindBlogs::Execute()
{
AnsiString keyword = Form1->Edit1->Text;
AnsiString seiten = StrToInt(Form1->Edit2->Text);
}
}
C/C++ Code:
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
//---------------------------------------------------------------------------

#include
<vcl.h>
#pragma
hdrstop

#include
"Unit2.h"
#include
"Unit1.h"
#pragma
package(smart_init)

AnsiString puffer = "";
TStringList* text = new TStringList(); //<- Die globale Stringlist die nachher //noch in Unit 1.cpp gebraucht wird

//---------------------------------------------------------------------------


__fastcall FindBlogs::FindBlogs(bool CreateSuspended)
: TThread(CreateSuspended)
{
FreeOnTerminate;
}

void __fastcall FindBlogs::updatetext()
{

}

//---------------------------------------------------------------------------
void __fastcall FindBlogs::Execute()
{
AnsiString keyword = Form1->Edit1->Text;
AnsiString seiten = StrToInt(Form1->Edit2->Text);
}
}
C/C++ Code:
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
//---------------------------------------------------------------------------

#include
<vcl.h>
#pragma
hdrstop

#include
"Unit2.h"
#include
"Unit1.h"
#pragma
package(smart_init)

AnsiString puffer = "";
TStringList* text = new TStringList();  //<- Die globale Stringlist die nachher //noch in Unit 1.cpp gebraucht wird

//---------------------------------------------------------------------------


__fastcall FindBlogs::FindBlogs(bool CreateSuspended)
        : TThread(CreateSuspended)
{
   FreeOnTerminate;
}

void __fastcall FindBlogs::updatetext()
{

}

//---------------------------------------------------------------------------
void __fastcall FindBlogs::Execute()
{
AnsiString keyword = Form1->Edit1->Text;
AnsiString seiten = StrToInt(Form1->Edit2->Text);
}
}



HIER
C/C++ Code:
AnsiString keyword = Form1->Edit1->Text;
AnsiString seiten = StrToInt(Form1->Edit2->Text);
C/C++ Code:
AnsiString keyword = Form1->Edit1->Text;
AnsiString seiten = StrToInt(Form1->Edit2->Text);
C/C++ Code:
AnsiString keyword = Form1->Edit1->Text;
AnsiString seiten = StrToInt(Form1->Edit2->Text);
scheint der Fehler ausgelöst zu werden. Wenn die Daten aus Form1 in den Thread übergeben werden crasht das Programm... :confused:
Wiesel666
Unregistrierter




Beitrag Wiesel666 Unregistrierter 14:52:54 21.01.2010   Titel:              Zitieren

Diese Linker-warnungen bekomme ich:

Zitat:
[Linker Warning] Public symbol '_puffer' defined in both module C:\*\UNIT1.OBJ and
C:\*\UNIT2.OBJ

[Linker Warning] Public symbol '_text' defined in both module
C:\*\UNIT1.OBJ and
C:\*\UNIT2.OBJ
Unregistrierter





Beitrag Unregistrierter 15:39:04 21.01.2010   Titel:              Zitieren

Du musst auch Synchronize() verwenden, wenn Du Daten aus Form1 liest, nicht nur beim Schreiben.

Und was soll das FreeOnTerminate im Konstruktor? So bewirkt das rein gar nichts. Du musst das entweder auf true oder false setzen.

Was ist denn der Zweck der beiden Variablen, bei denen Du die Linkerwarnung bekommst? Wenn Du sie jeweils in den Units brauchst, mach sie private. Wenn die zum Datenaustausch zwischen den Units gedacht sind, brauchst Du die nur einmal.
Wiesel666
Unregistrierter




Beitrag Wiesel666 Unregistrierter 17:07:43 21.01.2010   Titel:              Zitieren

Die StringList brauche ich in Unit1 und Unit 2. Dann werde ich die puffer-variable mal private deklarieren.


C/C++ Code:
void __fastcall FindBlogs::SyncText()
{
  sourcecode = puffer;
  start= 1;
  Form1->Memo1->Text = "text in puffer !";
}
C/C++ Code:
void __fastcall FindBlogs::SyncText()
{
sourcecode = puffer;
start= 1;
Form1->Memo1->Text = "text in puffer !";
}
C/C++ Code:
void __fastcall FindBlogs::SyncText()
{
  sourcecode = puffer;
  start= 1;
  Form1->Memo1->Text = "text in puffer !";
}


Hier setze ich die globale Variable start auf 1, wenn "sourcecode" einen bestimmt String enthält. Mein Ziel ist jetzt, einen zweiten Thread zu starten, der so lange wartet bis start auf 1 gesetzt wird:

_
C/C++ Code:
public:

        __fastcall FindBlogs(bool CreateSuspended);
};
int start = 0;
AnsiString puffer = "";
TStringList* text  = new TStringList();
C/C++ Code:
public:

__fastcall FindBlogs(bool CreateSuspended);
};
int start = 0;
AnsiString puffer = "";
TStringList* text = new TStringList();
C/C++ Code:
public:

        __fastcall FindBlogs(bool CreateSuspended);
};
int start = 0;
AnsiString puffer = "";
TStringList* text  = new TStringList();



C/C++ Code:
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
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
//---------------------------------------------------------------------------

#include
<vcl.h>
#pragma
hdrstop


#include
"Unit3.h"
#include
"Unit2.h"
#include
"Unit1.h"

#pragma
package(smart_init)

//---------------------------------------------------------------------------

__fastcall SentThread::SentThread(bool CreateSuspended)
        : TThread(CreateSuspended)
{
    FreeOnTerminate = true;
}
//---------------------------------------------------------------------------
void __fastcall SentThread::startposting()
{
  Form1->Memo1->Text = "Start posting !";
}
//---------------------------------------------------------------------------
void __fastcall SentThread::Execute()
{
       while(1)
       {
         if(start> 0)
         {
            Synchronize(&startposting);
          }
          Idglobal::Sleep(0);
       }
}
//---------------------------------------------------------------------------
C/C++ Code:
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
//---------------------------------------------------------------------------

#include
<vcl.h>
#pragma
hdrstop


#include
"Unit3.h"
#include
"Unit2.h"
#include
"Unit1.h"

#pragma
package(smart_init)

//---------------------------------------------------------------------------

__fastcall SentThread::SentThread(bool CreateSuspended)
: TThread(CreateSuspended)
{
FreeOnTerminate = true;
}
//---------------------------------------------------------------------------
void __fastcall SentThread::startposting()
{
Form1->Memo1->Text = "Start posting !";
}
//---------------------------------------------------------------------------
void __fastcall SentThread::Execute()
{
while(1)
{
if(start> 0)
{
Synchronize(&startposting);
}
Idglobal::Sleep(0);
}
}
//---------------------------------------------------------------------------
C/C++ Code:
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
//---------------------------------------------------------------------------

#include
<vcl.h>
#pragma
hdrstop


#include
"Unit3.h"
#include
"Unit2.h"
#include
"Unit1.h"

#pragma
package(smart_init)

//---------------------------------------------------------------------------

__fastcall SentThread::SentThread(bool CreateSuspended)
        : TThread(CreateSuspended)
{
    FreeOnTerminate = true;
}
//---------------------------------------------------------------------------
void __fastcall SentThread::startposting()
{
  Form1->Memo1->Text = "Start posting !";
}
//---------------------------------------------------------------------------
void __fastcall SentThread::Execute()
{
       while(1)
       {
         if(start> 0)
         {
            Synchronize(&startposting);
          }
          Idglobal::Sleep(0);
       }
}
//---------------------------------------------------------------------------


Was passiert ? garnix...

Thread 1 und 2 werden aus dem Hauptthread gestartet. Thread 1 setzt "start" auf 1. In Thread 2 wird aber nicht erkannt, dass start auf 2 gesetzt wurde.
Auf jeden Fall springt er nicht in die if-schleife rein.
Killer-Kobold
Mitglied

Benutzerprofil
Anmeldungsdatum: 16.03.2009
Beiträge: 180
Beitrag Killer-Kobold Mitglied 17:20:32 21.01.2010   Titel:              Zitieren

Mal von den Logikfehlern abgesehen. Du MUSST jeglichen Datenaustausch Threadsicher gestalten. Du darfst nicht einfach wild Variablen aus anderen Threads lesen und/oder schreiben. Siehe TCriticalSection (mir persönlich gefält das Pendant aus der WinAPI besser), oder eine der anderen Möglichkeiten.

Um mitzuteilen, dass ein bestimmter Status eingetreten ist, verwendet man das Botschaftssystem, oder eine der anderen diversen Möglichkeiten, zB Events oder Semaphores in Verbindung mit WaitForSingleObject oder WaitForMultipleObjects. Niemals, ich wiederhole, niemals! pollt man auf einen Status, das verbraucht einfach nur unnötig CPU-Zeit (und das nicht unerheblich).

Gruß KK
Wiesel666
Unregistrierter




Beitrag Wiesel666 Unregistrierter 18:00:28 21.01.2010   Titel:              Zitieren

Ich habe deine Tipps befolgt und das ganze umgeschrieben:

Unit2.cpp:
C/C++ Code:
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
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
void __fastcall FindBlogs::SyncText()
{
  sourcecode = puffer;
  Form1->Memo1->Text = "text in puffer !";
  SetEvent ( hEvent );
}

void __fastcall FindBlogs::updatetext()
{
  Form1->Label1->Caption = "Threads running: " + IntToStr(threadsrunning);
}

void __fastcall FindBlogs::GetInput()
{
AnsiString keyword = Form1->Edit1->Text;
int seiten = StrToInt(Form1->Edit2->Text);
}

//---------------------------------------------------------------------------
void __fastcall FindBlogs::Execute()
{

HANDLE hEvent = CreateEvent ( NULL, FALSE, FALSE, "quelltext");
threadsrunning++;

Synchronize(&updatetext);
Synchronize(&GetInput);

Synchronize(&SyncText);

DeleteThread();
}
C/C++ Code:
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
void __fastcall FindBlogs::SyncText()
{
sourcecode = puffer;
Form1->Memo1->Text = "text in puffer !";
SetEvent ( hEvent );
}

void __fastcall FindBlogs::updatetext()
{
Form1->Label1->Caption = "Threads running: " + IntToStr(threadsrunning);
}

void __fastcall FindBlogs::GetInput()
{
AnsiString keyword = Form1->Edit1->Text;
int seiten = StrToInt(Form1->Edit2->Text);
}

//---------------------------------------------------------------------------
void __fastcall FindBlogs::Execute()
{

HANDLE hEvent = CreateEvent ( NULL, FALSE, FALSE, "quelltext");
threadsrunning++;

Synchronize(&updatetext);
Synchronize(&GetInput);

Synchronize(&SyncText);

DeleteThread();
}
C/C++ Code:
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
void __fastcall FindBlogs::SyncText()
{
  sourcecode = puffer;
  Form1->Memo1->Text = "text in puffer !";
  SetEvent ( hEvent );
}

void __fastcall FindBlogs::updatetext()
{
  Form1->Label1->Caption = "Threads running: " + IntToStr(threadsrunning);
}

void __fastcall FindBlogs::GetInput()
{
AnsiString keyword = Form1->Edit1->Text;
int seiten = StrToInt(Form1->Edit2->Text);
}

//---------------------------------------------------------------------------
void __fastcall FindBlogs::Execute()
{

HANDLE hEvent = CreateEvent ( NULL, FALSE, FALSE, "quelltext");
threadsrunning++;

Synchronize(&updatetext);
Synchronize(&GetInput);

Synchronize(&SyncText);

DeleteThread();
}


Unit3.cpp:

C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//---------------------------------------------------------------------------

__fastcall SentThread::SentThread(bool CreateSuspended)
        : TThread(CreateSuspended)
{
    FreeOnTerminate = true;
}
//---------------------------------------------------------------------------
void __fastcall SentThread::startposting()
{
  Form1->Memo1->Text = "Start posting !";
}
//---------------------------------------------------------------------------
void __fastcall SentThread::Execute()
{
       while(WaitForSingleObject ( hEvent, INFINITE) != WAIT_OBJECT_0)
       {

       }
  Synchronize(&startposting);
}
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//---------------------------------------------------------------------------

__fastcall SentThread::SentThread(bool CreateSuspended)
: TThread(CreateSuspended)
{
FreeOnTerminate = true;
}
//---------------------------------------------------------------------------
void __fastcall SentThread::startposting()
{
Form1->Memo1->Text = "Start posting !";
}
//---------------------------------------------------------------------------
void __fastcall SentThread::Execute()
{
while(WaitForSingleObject ( hEvent, INFINITE) != WAIT_OBJECT_0)
{

}
Synchronize(&startposting);
}
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//---------------------------------------------------------------------------

__fastcall SentThread::SentThread(bool CreateSuspended)
        : TThread(CreateSuspended)
{
    FreeOnTerminate = true;
}
//---------------------------------------------------------------------------
void __fastcall SentThread::startposting()
{
  Form1->Memo1->Text = "Start posting !";
}
//---------------------------------------------------------------------------
void __fastcall SentThread::Execute()
{
       while(WaitForSingleObject ( hEvent, INFINITE) != WAIT_OBJECT_0)
       {

       }
  Synchronize(&startposting);
}


"hEvent" ist global in Unit2.cpp deklariert:

C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#ifndef Unit2H
#define
Unit2H
//---------------------------------------------------------------------------
#include
<Classes.hpp>
//---------------------------------------------------------------------------


class FindBlogs : public TThread
{
private:
        AnsiString keyword;
        int seiten;
protected:
        ....funktionen
public:
        ..............
};

HANDLE hEvent;
AnsiString puffer = "";
TStringList* text  = new TStringList();
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#ifndef Unit2H
#define
Unit2H
//---------------------------------------------------------------------------
#include
<Classes.hpp>
//---------------------------------------------------------------------------


class FindBlogs : public TThread
{
private:
AnsiString keyword;
int seiten;
protected:
....funktionen
public:
..............
};

HANDLE hEvent;
AnsiString puffer = "";
TStringList* text = new TStringList();
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#ifndef Unit2H
#define
Unit2H
//---------------------------------------------------------------------------
#include
<Classes.hpp>
//---------------------------------------------------------------------------


class FindBlogs : public TThread
{
private:
        AnsiString keyword;
        int seiten;
protected:
        ....funktionen
public:
        ..............
};

HANDLE hEvent;
AnsiString puffer = "";
TStringList* text  = new TStringList();
Wiesel666
Unregistrierter




Beitrag Wiesel666 Unregistrierter 18:02:10 21.01.2010   Titel:              Zitieren

Sorry für das Doppelposting. Ich kann den Beitrag leider nicht editieren:

Das ganze funktioniert so anscheinend auch nicht. Er springt nicht mehr aus der
while(WaitForSingleObject -schleife im Thread 3 raus.
C/C++ Forum :: VCL (C++ Builder) ::  Thread-Problem  
Gehen Sie zu Seite 1, 2  Weiter
Auf Beitrag antworten

Zeige alle Beiträge auf einer Seite




Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Sie können Beiträge in dieses Forum schreiben.
Sie können auf Beiträge in diesem Forum antworten.
Sie können Ihre Beiträge in diesem Forum nicht bearbeiten.
Sie können Ihre Beiträge in diesem Forum nicht löschen.
Sie können an Umfragen in diesem Forum nicht mitmachen.

Powered by phpBB © 2001, 2002 phpBB Group :: FI Theme

c++.de ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de Werbekostenerstattung verdient werden kann.

Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info, www.c-sar.de, www.c-plusplus.net und www.baeckmann.de enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt (vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden. Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.