Autor
Nachricht
Wiesel666
Unregistrierter
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
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
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
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...
Wiesel666
Unregistrierter
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
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
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
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
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
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.
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.