Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.72/18: Рейтинг темы: голосов - 18, средняя оценка - 4.72
Каждому свое
 Аватар для Bretbas
533 / 219 / 81
Регистрация: 05.08.2013
Сообщений: 1,614

Статический метод как точка входа в поток - как избавиться

07.01.2014, 23:21. Показов 3710. Ответов 19
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Привет всем.Вопрос такой: использую потоки в своей программе,они создаются и уничтожаются в классе, и в классе так же находится метод,который является точкой входа потока.Суть в том,что если эта точка входа находится в классе,то ее нужно обьявлять как static,что мне не подходит,так как все объекты,находящиеся в этом методе нужно тоже делать статическими,а их довольно много.Собственно вот и нарисовывается сам вопрос - как избавиться от этой "статичности"?)Искал в гугле,не понял ничего)можете подробнее объяснить как это сделать?
Использую winapi для работы с потоками
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
07.01.2014, 23:21
Ответы с готовыми решениями:

Как объявить статический метод класса?
выдает ошибку на 11 16 19 строку((((((( #include <iostream> using namespace std; class Sop { private: short int kol; ...

Как правильно объявить статический метод
например class A { private: static void method(); // объявление }; // как правильно объявить реализацию?

Как передать нестатическое поле в статический метод класса?
есть статическая фукция static LRESULT CALLBACK WndProc ( HWND,UINT,WPARAM,LPARAM); в ней нужно использоавть поля класса, вопрос -...

19
Псевдослучайный
1946 / 1146 / 98
Регистрация: 13.09.2011
Сообщений: 3,215
08.01.2014, 00:02
Что мешает использовать в качестве точки входа специально обученную функцию, вызывающую какие угодно методы?
0
DU
1500 / 1146 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
08.01.2014, 00:06
в новом стандарте такой проблемы нет.
но если он по какой-то причине не доступен, то:
в татическую фунцию передаете this. статическая функция обычно void* принимает.
она кастит этот void* к типу самого класса и вот в статической фунции у вас
есть указатель на инстанс класса. вызываете у него какие хотите методы, ведь
статической функции доступны все методы\мемберы через этот указатель.
0
13 / 13 / 5
Регистрация: 29.06.2011
Сообщений: 85
08.01.2014, 00:10
Создаёте статическую функцию, которая будет являтся дружественной для нужного класса(ThreadProc).
Затем создаёте простую функцию (член) класса, которая должна выполнять необходимые действия.
В CreateThread передаёте указатель на статическую функцию, а в качестве lpParametr передаёте указатель на класс, в котором находится нужная функция член.
Затем в ThreadProc пишите:
return ((ВАШ_КЛАСС*)lpParametr->ФУНКЦИЯ_ЧЛЕН());
0
 Аватар для DiffEreD
1458 / 795 / 257
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
08.01.2014, 00:10
Может воспользоваться тем что предлагает C++11:
C++
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
#include <iostream>
#include <thread>
 
class some_class
{
   mutable std::thread t;
   int val = 100;
public:
   void foo(int n) const
   {
      for (int i = 0; i < n; ++i)
         std::cout << "Hello from foo. val = " << val << "\n";
   }
 
   void create_thread() const
   {
      t = std::thread(&some_class::foo, this, 5);
      t.join();
   }
};
 
int main()
{
   some_class sm;
   sm.create_thread();
 
   return 0;
}
0
Каждому свое
 Аватар для Bretbas
533 / 219 / 81
Регистрация: 05.08.2013
Сообщений: 1,614
08.01.2014, 14:19  [ТС]
А как именно передать this через передаваемый указатель в статическом методе?можете привести пример?
С стандартной библиотекой <thread> знаком,но мне нужно именно winapi
0
DU
1500 / 1146 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
08.01.2014, 14:33
свой винапишный код покажите. с ним проще будет объяснить.
0
Каждому свое
 Аватар для Bretbas
533 / 219 / 81
Регистрация: 05.08.2013
Сообщений: 1,614
09.01.2014, 00:13  [ТС]
Я пишу вам с мобильного телефона,интернета на компьютере нет,поэтому сложно будет написать вам код,потому что он достаточно весомый...
Короче у меня есть есть два класса _figure и _area.В классе _figure имеется метод,который мне нужно выполнять в новом потоке - DWORD WINAPI MoveDown(PVOID).В классе _area есть метод void Start() в котором имеется указатель на класс _figure.И как раз в методе Stast() мне нужно заводить как раз второй поток с точкой входа MoveDown(...).Поток завожу функцией CreateThread(...) ,куда передаю собственно функцию MoveDown(...) и указатель на класс _figure.Суть в том,что мне нужно делать эту точку входа статической,и следовательно все методы и поля,которые там используются(в частности они все являются данными класса _figure) нужно делать тоже статическими,что меня категорически не устраивает...
Вот собственно рассказал на словах Вам мой код...Помогите пожалуйста
0
DU
1500 / 1146 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
09.01.2014, 00:20
вот так я надеюсь будет понятно:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
class Figure
{
public:
  void MoveDown()
  {
    // ...
  }
 
  static void MoveDown(PVOID figure)
  {
    static_cast<Figure*>(figure)->MoveDown();
  }
};
т.е. по прежнему вызывается статический метод, но ему передается указатель на инстанс класса.
этот void* кастится к Figure* и тут же вызывается его метод. в результате метод будет вызван в
отдельном потоке для отдельного инстанса. никаких статических полей не надо.
0
Каждому свое
 Аватар для Bretbas
533 / 219 / 81
Регистрация: 05.08.2013
Сообщений: 1,614
09.01.2014, 23:08  [ТС]
Во!всё заработало!спасибо большое...теперь всё понятно)
0
║XLR8║
 Аватар для outoftime
1212 / 909 / 270
Регистрация: 25.07.2009
Сообщений: 4,360
Записей в блоге: 5
09.01.2014, 23:20
Bretbas, я не читал все посты. Но мне кажется паттерн одиночка (singletone) подходит как никто другой.

Добавлено через 2 минуты
http://en.wikipedia.org/wiki/Singleton_pattern
0
Каждому свое
 Аватар для Bretbas
533 / 219 / 81
Регистрация: 05.08.2013
Сообщений: 1,614
10.01.2014, 23:59  [ТС]
Слушайте,а не поможете сделать обертку в виде класса для создания потока?Чтобы в конструктор я передавал название функции,которая будет использована как точка входа в поток,потом название класса где выполняется поток и сам объект на параметры?И чтобы статический метод этот был внутри класса,и меня не затрагивал
0
Каждому свое
 Аватар для Bretbas
533 / 219 / 81
Регистрация: 05.08.2013
Сообщений: 1,614
12.01.2014, 00:57  [ТС]
Ммм?
0
DU
1500 / 1146 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
12.01.2014, 01:04
если нет возможности использовать новый стандарт, то все равно лучше воспользоваться чем-то готовым.
boost, tbb, ...

если писать универсальную вещь, то код будет досаточно хитрый, с кучей шаблонов и все равно скорее всего криво получится.
1
Каждому свое
 Аватар для Bretbas
533 / 219 / 81
Регистрация: 05.08.2013
Сообщений: 1,614
13.01.2014, 02:50  [ТС]
Да я хотел тупо обертку сделать,чтобы был класс,для создание потока, и чтобы. для каждого потока имелся свой экземпляр класса,куда через конструктор передается функция-метод,котороя потом вызывается в статическом методе этого класса.Вот типо такого что-то))
А еще...как мне передать формальный параметр в функцию,которая является точкой входа в поток?
C++
1
2
3
4
5
6
7
8
...
class primer
public:
void funcmain(int i);
static DWORD WINAPI fun(PVOID object)
{
static_cast<primer*>object -> funcmain(что сюда передать и как);
...
Вот примерчик набросал...тяжело с мобилы объяснять:-)
0
DU
1500 / 1146 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
13.01.2014, 23:04
C++
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
class primer
{
public:
  void funcmain(int i);
};
 
struct ObjAndParam
{
  primer* obj;
  int param;
};
 
static void ThreadFun(void* data)
{
  ObjAndParam* objAndParam = static_cast<ObjAndParam*>(data);
  objAndParam->obj->funcmain(objAndParam->param);
}
 
 
Простейший вариант:
Через data нужно передать как-то объект и параметры для вызова.
Значит перед вызовом нужно создать объект ObjAndParam и посетить
в него нужные данные.
Но дальше начинаются сложности.
Если мы отдаим указатель на объект на стеке - значит нужно
как-то гарантировать, что ThreadFun вызовытся до разрушения
этого объекта. Если его создавать динамически, то нужно
как-то гарантированно его удалять. + не забываем о том,
что объект пример должнен быть живым в момент вызова
метода из другого потока. Добавляем сюда обработку
всяких исключений и ошибок для надежной работы, добавляем
возможность это делать для объектов любых типов, для вызова
любых методов с любым (ну даже с ограниченным) количеством
аргументов любых типов - получаем хитрую шаблонную магию
и всякие другие фокусы для надежной работы. Осознаем что это
все достаточно сложно и возвращаемся к выбору какого-нибудь
готового решения.
1
Каждому свое
 Аватар для Bretbas
533 / 219 / 81
Регистрация: 05.08.2013
Сообщений: 1,614
14.01.2014, 01:10  [ТС]
Готового решения вы имеете ввиду библиотеку типа <thread>?
0
DU
1500 / 1146 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
14.01.2014, 11:15
да.
0
Каждому свое
 Аватар для Bretbas
533 / 219 / 81
Регистрация: 05.08.2013
Сообщений: 1,614
19.01.2014, 01:22  [ТС]
Я отказался то этой библиотеки по той причине,потому что там нет таких функций как приостановить поток и возобновить его(ResumeThread(...) к примеру) как на винапи))
Если вы опровергнете мой слова,или подскажете какое-нибудь подобие этих функций,то я буду очень благодарен и у меня будут мысли о том,чтобы вернуться к этой библиотеки))
0
DU
1500 / 1146 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
19.01.2014, 12:48
похоже что новый стандарт вам доступен и вы сможете вот такой пример скомпилять:
C++
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
#include <functional>
#include <memory>
#include <string>
#include <iostream>
 
//////////////////////////////////////////////////////
// аналог апишной функции. считаем что она запускает
// переданную функцию в отдельном потоке
typedef void (ThreadFuncPtr)(void*);
void RunThread(ThreadFuncPtr threadFunc, void* param)
{
  threadFunc(param);
}
//////////////////////////////////////////////////////
 
// наш класс помошник
class RunThreadHelper
{
  // если новый стандарт недоступен, то
  // этой штуке есть альтернатива:
  // абстрактный класс с одной функцией.
  // но std::function - удобнее.
  typedef std::function<void ()> Operation;
 
public:
  static void Run(Operation operation)
  {
    // когда и как освобождать этот op - придумайте сами.
    // в простейшем случае - в ThreadFunction если все пошло хорошо.
    Operation* op = new Operation(std::move(operation));
    RunThread(&RunThreadHelper::ThreadFunction, op);
  }
 
private:
  static void ThreadFunction(void* param)
  {
    std::unique_ptr<Operation> op(static_cast<Operation*>(param));
    (*op)();
  };
};
 
 
void FreeFunction1()
{
  std::cout << "FreeFunction1" << std::endl;
}
 
void FreeFunction2(int param)
{
  std::cout << "FreeFunction2: param = " << param << std::endl;
}
 
void FreeFunction3(int param1, const std::string& param2)
{
  std::cout << "FreeFunction3: param1 = " << param1 << "; param2 = " << param2 << std::endl;
}
 
class Test
{
  std::string m_name;
 
public:
  Test(const std::string& name)
    : m_name(name)
  {
  }
 
  void Function1()
  {
    std::cout << "Test::Function1: m_name = " << m_name << std::endl;
  }
 
  void Function2(int param)
  {
    std::cout << "Test::Function2: m_name = " << m_name << "; param = " << param << std::endl;
  }
 
  void Function3(int param1, const std::string& param2)
  {
    std::cout << "Test::Function3: m_name = " << m_name << "; param1 = " << param1 << "; param2 = " << param2 << std::endl;
  }
};
 
 
int main()
{
  Test test1("test1");
  Test test2("test1");
 
  RunThreadHelper::Run(&FreeFunction1);
 
  RunThreadHelper::Run(std::bind(&FreeFunction2, 2));
  RunThreadHelper::Run([] { FreeFunction2(22); });
  RunThreadHelper::Run(std::bind(&Test::Function1, &test1));
  RunThreadHelper::Run(std::bind(&Test::Function2, &test1, 2));
  RunThreadHelper::Run(std::bind(&Test::Function3, &test1, 2, "x"));
 
  RunThreadHelper::Run(std::bind(&FreeFunction3, 3, "x"));
  RunThreadHelper::Run([] { FreeFunction3(33, "xx"); });
  RunThreadHelper::Run([&test2] { test2.Function1(); });
  RunThreadHelper::Run([&test2] { test2.Function2(2); });
  RunThreadHelper::Run([&test2] { test2.Function3(22, "xx"); });
 
  return 0;
}
Добавлено через 7 минут
C++
1
2
3
4
5
6
7
8
  static void ThreadFunction(void* param)
  {
    std::unique_ptr<Operation> op(static_cast<Operation*>(param));
    (*op)();
    // до сюда можем не дойти из-за исключения. нужно придумать как его не потерять
    // и донести до вызывающей стороны. какой-нибудь будущий результат из std использовать
    // или еще как-то.
  };
Добавлено через 10 часов 47 минут
на счет станартной библиотеки:
у std::thread есть такие методы:

std::thread::get_id - returns the id of the thread
std::thread::native_handle - returns the underlying implementation-defined thread handle

я сам не пробовал, но похоже на то, что то, что они возвращают можно использовать
в винапишных функциях после соответствующего каста. Т.е. можно зарезьюмить и засаспендить
интересующий поток.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
19.01.2014, 12:48
Помогаю со студенческими работами здесь

Программа не содержит статический метод "Main", подходящий для точки входа
Рыл форум, пробывал что-то сделать, не вышло, прошу помочь. Выбрасывает 2 ошибки: Программа не содержит статический метод...

Приложение не содержит статический метод "Main", подходящий для точки входа
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ip_ca { class iputils ...

Программа не содержит статический метод "Main", подходящий для точки входа
Помогите не пойму где ошибка using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace OOP...

Единая точка входа, как в htaccess
Пробовал конвертировать с помощью сервисов мой апачевский htaccess для ngnix не проканало. Подскажите или готовый пример для редиректа...

Как вызвать статический метод в обработчике событий?
static class DbMethod { static void Connect(System.Data.Common.DbConnection sqlConnection1) { var connectionString =...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru