User 11061201 Ответов: 1

Класс C++, который использует таймер с потоком сбоев с использованием 2 рекурсивных обратных вызовов


Привет, сообщество, я, кажется, не могу найти решение моей текущей проблемы. У меня есть 2 класса, которые запускают определенные процедуры с таймерами в отдельном потоке. Таймер, который я написал, работает по тем же принципам, что и другой, но приложение выходит из строя, когда мне нужно вызвать обратный вызов из класса, который вызвал таймер.

У меня есть класс А, который инициализируется из main.cpp. Затем класс А должен инициализировать класс Альфа и класс бета. Альфа и бета используют класс Timer. Класс Timer правильно вызывает процедуры на Alpha и Beta, но эти две процедуры не вызывают процедуру на класс A. Приложение прекрасно компилируется и разбивается только во время вызова.
Сигнатура проблемы :
Имя события проблемы: APPCRASH
Название Приложения: MyProgram.exe
Версия Приложения: 0.0.0.0
Отметка Времени Приложения: 00050000
Имя Модуля Неисправности: StackHash_5861
Версия Модуля Неисправности: 0.0.0.0
Временная Метка Модуля Неисправности: 00000000
Код исключения: c0000005
Смещение исключения: PCH_72_FROM_ntdll+0x00072DA4
Версия ОС: 6.3.9600.2.0.0.256.48
Код языка: 1033
Дополнительные Сведения 1: 5861
Дополнительные сведения 2: 5861822e1919d7c014bbb064c64908b2
Дополнительная Информация 3: 4754
Дополнительная информация 4: 47547fafc9a3073a5bbe8e69322a8db5




//main.cpp with WINAPI using the WINAPI loop

A a1;
a1.Initialize();



//A
void Initialize()
{
Alpha alpha1;     
alpha1.Create(&SHandler);
}
static void SHandler(string info)
{
A a1;
a1.Handler(info)
}
void Handler(string info)
{printf(info);}



//Alpha
void (*_AddressAt)(string info);
void Create(void (*AddressAt)(string info))
{
_AddressAt = AddressAt;
Timer Timer1;
Timer1.AddHandler(&Shandler);
Timer1.Interval = 1000;
Timer1.Start();
}
static void SHandler()
{
Alpha alpha1;
alpha1.Handler();
}
void Handler()
{
_AddressAt("CallBack!"); //LINE THAT CRASHES APP 
}


//Timer.h
#pragma once

class Timer
{
public:
    DWORD Interval = 1000;
    bool IsRunning();
    void AddHandler(void (*AddressOf)(void));
    void Start();
    void Stop();
private:
    void (*_AddressOf)(void);
    void Looper();
    bool _IsRunning = false;
};

//Timer.cpp
#include <windows.h>
#include <thread>
#include "Timer.h"

using namespace std;
void Timer::AddHandler(void (*AddressOf)(void))
{
    _AddressOf = AddressOf;
}

void Timer::Start()
{
    _IsRunning = true;
    std::thread first(Looper, this);
    first.join();
}

void Timer::Stop()
{
    _IsRunning = false;
}

void Timer::Looper()
{
    while (_IsRunning)
    {
        _AddressOf(); // make callback
        Sleep(Interval);
    }
}

bool Timer::IsRunning()
{
    return _IsRunning;
}


Что я уже пробовал:

---------------------------------------------------------

Richard MacCutchan

Объект alpha1 не существует после возврата из вызова в a1.Initialize Ваш код слишком сложен и труден для понимания.

KarstenK

Опубликуйте его в качестве ответа, чтобы закрыть вопрос и ответ.

Philippe Mori

Изучите C++ и многопоточность. Вы должны понять время жизни объекта. Например, таймер создания функции является локальным для этой функции. Без таких базовых знаний вы не должны пытаться делать многопоточность... как вам нужно понять, что вы делаете в первую очередь....

1 Ответов

Рейтинг:
10

KarstenK

Вы должны изменить область действия вашего объекта на более высокий уровень. Некоторые из них только существуют по охвату такой функции, как Шандлер. (После выхода из функции объекты уничтожаются)