Laszlo900 Temat założony przez niniejszego użytkownika |
[C++/CLI, Visual Studio 2012] Problem z wątkami z biblioteki System::Thread » 2014-08-26 00:10:25 Witajcie, mam nadzieję, że trafiłem dobrze i żadnego nadgorliwca nie zbulwersuję. Jestem raczej paraprogramistą. Tworzyłem na własne potrzeby aplikację win32 w Visual Studio 2012, w której korzystałem z biblioteki <thread>. Kiedy postanowiłem dodać obsługę okienkową Windows Forms, projekt zmienił się z win32 na clr, które nie wspiera bibl. <thread>. Korzystam więc z nowej biblioteki: System::Thread. W aplikacji, dane przychodzące do pewnego bufora trafiają następnie w każdej iteracji do osobnych wątków, gdzie są wyświetlane na wykresach. Po wysłaniu iteracyjnie danej do każdego wątku, operacja jest powtarzana. Liczba obiektów jest z góry znana - wprowadzona w wyświetlonym okienku Windows Forms. Problem polega na tym, że nie mogę do wektora std::vector<NazwaKlasy^>NazwaWektora dodać obiektu wątku metodą NazwaWektora[NumerPorzadkowy].push_back(NazwaObiektuWatku), ponieważ zwracany jest błąd:
"error C3699: '&&' : cannot use this indirection on type NazwaKlasy^"
Czytałem o obsłudze tych daszków ^ oraz delegatów na MSDN, jednak po wielu najróżniejszych próbach postanowiłem zwrócić się z problemem na forum. Dodam, że mamy tu do czynienia z tzw. "managed class", opisywaną przez ref class NazwaKlasy. Bez pożądanego wektora, miałem jedynie możliwość tworzenia ręcznie po kolei wątków następującymi poleceniami (wątki z obsługiwanym zewnętrznie parametrem): 1: ThreadWithState^ tws = gcnew ThreadWithState(); 2: Thread^ t = gcnew Thread( gcnew ThreadStart(tws, &ThreadWithState::ThreadProc ) );
Ktoś ma pomysł jak dodać iteracyjnie obiekty wątków (wątki) do tego lub podobnego wektora, tak, aby móc dynamicznie modyfikować atrybuty wątków?
Załączam definicję klasy:
ref class ThreadWithState { public: float* zmienna; //proszę nie krzyczeć, ona będzie prywatna, z metodą dostępową
ThreadWithState() { }
void ThreadProc() { Wykres* wykres1 = new Wykres(); wykres1->rysuj(zmienna);
} };
Wątki są tworzone zgodnie z przykładem z MSDN: http://msdn.microsoft.com/en-us/library/ts553s52(v=vs.110).aspx?cs-save-lang=1&cs-lang=cpp#code-snippet-1
|
|
DejaVu |
» 2014-08-26 00:53:52 Daszek to nie delegat. Daszek to wskaźnik na pamięć zarządzaną (występuje managed C++), a gwiazdka to wskaźnik na pamięć niezarządzaną. Skoro trzymasz w vectorze wskaźniki zarządzane to musisz po prostu zaalokować taki obiekt dynamicznie. /edit: Upraszczając: std::vector < int ^> kontener; kontener.push_back( gcnew int( 123 ) );
|
|
Laszlo900 Temat założony przez niniejszego użytkownika |
» 2014-08-26 01:23:47 Dzięki wielkie za szybką odpowiedź i sugestię. Spróbowałem pokombinować, jednak nie podołałem problemowi. Wiedząc, na jakim miejscu się skupić, daję namiar na kod:
std::vector<ThreadWithState^> ThreadsWithState; std::vector<Thread^> Threads;
ThreadWithState^ tws = gcnew ThreadWithState(); ThreadsWithState.push_back(tws); Thread^ t = gcnew Thread( gcnew ThreadStart(tws, &ThreadWithState::ThreadProc ) ); Threads.push_back(t);
Niestety, zmieniwszy ThreadsWithState.push_back(tws) na ThreadsWithState.push_back(gcnew ThreadWithState(tws)), bądź na ThreadsWithState.push_back(gcnew ThreadWithState()) i inne, podobne kombinacje, wyskakuje błąd o zbyt dużej ilości argumentów funkcji
Dla: ThreadWithState^ tws = gcnew ThreadWithState(); ThreadsWithState.push_back(gcnew ThreadWithState()); Thread^ t = gcnew Thread( gcnew ThreadStart(tws, &ThreadWithState::ThreadProc ) ); Threads.push_back(gcnew Thread(gcnew ThreadStart(tws, &ThreadWithState::ThreadProc ) ));
przynajmniej nie podkreśla składni, ale przy kompilacji jest znowu tylko błąd opisywany w temacie. Kończą mi się pomysły i chyba czekają mnie długie godziny z dokumentacją MSDN. Z góry dziękuję za następne sugestie |
|
DejaVu |
» 2014-08-26 01:31:16 |
|
Laszlo900 Temat założony przez niniejszego użytkownika |
» 2014-08-28 00:34:53 Dzięki raz jeszcze. Niestety na drodze wielogodzinnych prób przy pomocy MSDN, potwierdzałby się fakt, że takiego szpagatu zrobić się nie da. Proponowane zamienniki mojego wektora: List, set, array z tegoż samego frameworku nie mogą obsłużyć obiektów takich klas, mimo iż potencjalnie do podobnych rzeczy się nadają. W projekcie, na drodze desperacji, stworzyłem na stałe 10 wątków i bardzo brzydkiego switch case'a, który w zależności od liczby stworzonych obiektów, którym przypisywane są wątki, startuje tyle wątków, ile jest obiektów (a miało być tak pięknie). W MSDN kierują rozwiązanie do rzeczy takich, jak np. BackgroundWorker, bazującego zdaje się na eventach, ale wgryzienie się w to zostawiam na koniec projektu. |
|
« 1 » |