Arrow
ArrowMay 1, 2017, 1 a.m.

Callback функции

Callback функции, STL

Первый раз пытаюсь работать с Callback функциями. Помогите понять, что и где я не так делаю.

Вот код:

ReverseString.h

#ifndef REVERSESTRING_H
#define REVERSESTRING_H

#include <map>
#include <string>
using namespace std;

class ReverseString
{
public:
    ReverseString();
    ~ReverseString();
    // Получить буквенный шифр и перекодировать в цифровой
    void decode(const string data);
    // Установка функции обратного вызова
    void setCallBackFunc(void (*func) (string data));

private:
    // Список численных значений для букв
    map<char, int> m_map;
    // Возвращаемая строка
    string m_string;
    // Указатель на функцию обратного вызова (возвращает цифровой шифр)
    void (*callbackfunction) (string data);
};

#endif // REVERSESTRING_H

ReverseString.cpp

#include "reversestring.h"

ReverseString::ReverseString()
{
    // Перевод букв (шеснадцатеричные значения) в десятичные
    m_map = {{'A', 10 }, {'B', 11}, {'C', 12}, {'D', 13}, {'E', 14}, {'F', 15}};
}

ReverseString::~ReverseString()
{
    // Очистить данные
    m_map.clear();
    m_string.clear();
}

void ReverseString::decode(const string data)
{
    // Получить буквенный шифр и перекодировать в цифровой
    m_string.clear();
    // Прекодировка
    for (int i = 0; i < m_string.length(); ++i) {
        m_string += m_map.at(data.at(i));
    }
    // Вызвать функцию обратного вызова для возврата
    // кодированной строки
    callbackfunction(m_string);
}

void ReverseString::setCallBackFunc(void (*func) (string data))
{
    // Установка функции обратного вызова
    callbackfunction = func;
}

main.cpp

#include <QCoreApplication>
#include <string>
#include <iostream>
using namespace std;

#include "reversestring.h"

void codeStringView(string data)
{
    // Вывести кодированную строку
    // полученную от callback функции
    cout << data << endl;
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    string data;

    cout << "Enter string:" << endl;

    cin >> data;

    ReverseString *codeString = new ReverseString();

    // Установить функцию обратного вызова
    codeString->setCallBackFunc(codeStringView);

    codeString->decode(data);

    getchar();

    return a.exec();
}

Код написал от фонаря :) только для понимания как работает Callback функция.

We recommend hosting TIMEWEB
We recommend hosting TIMEWEB
Stable hosting, on which the social network EVILEG is located. For projects on Django we recommend VDS hosting.

Do you like it? Share on social networks!

7
Evgenii Legotckoi
  • May 1, 2017, 12:06 p.m.

Думаю, что здесь всё правильно сделано кроме одного единственного момента.

Функция, которая передаётся в качестве CallBack функции должна быть статической. Не статические функции не получится передать в качестве обычных CallBack функций.

static void codeStringView(string data)
{
    // Вывести кодированную строку
    // полученную от callback функции
    cout << data << endl;
}
    Arrow
    • May 2, 2017, 2:35 p.m.

    Программа запускается но результат не выводит. После ввода символа (А, В, С ... ) и нажатия Enter каретка переходит на новую строку и ничего не происходит. Нет ни ответа ни ошибки.

      Arrow
      • May 2, 2017, 2:37 p.m.

      Она просто продолжает работать - реагирует на все нажатия клавиш.

        Evgenii Legotckoi
        • May 2, 2017, 9:18 p.m.

        А дело оказалось вовсе не CallBack. Ошибка в следующем коде:

        Было

        for (int i = 0; i < m_string.length(); ++i) {
            m_string += m_map.at(data.at(i));
        }

        Стало

        for (int i = 0; i < data.length(); ++i) {
            m_string.append(to_string(m_map.at(data.at(i))));
        }

        Ошибки следующие:

        1. Проверка длины не той переменной. m_string.length() всегда будет равен нулю. Вы же его очищаете перед циклом.
        2. Добавлять к str::string нужно именно std::string. При попытке добавления данных переменной целочисленного типа - эта переменная воспринимается как код символа, а не как число 10, например.
        3. Поэтому нужно делать преобразование кода через std::to_string()
          Arrow
          • May 2, 2017, 11:13 p.m.

          Спасибо!

          Концентрировал внимание на CallBack и понадеялся, что все остальное написал правильно. :)

          Теперь программа вылетает и пишет ошибку:

          Запускается C:\Users\admin\Desktop\CallBackFunc\bild\Debug\debug\CallBackFunc.exe... Error - RtlWerpReportException failed with status code :-1073741823. Will try to launch the process directly C:\Users\admin\Desktop\CallBackFunc\bild\Debug\debug\CallBackFunc.exe завершился с кодом -1073741819

          По отладчику вылетает на строке:

          callbackfunction(m_string);

          С сообщением: Segmentation fault.

            Evgenii Legotckoi
            • May 2, 2017, 11:18 p.m.
            • The answer was marked as a solution.

            Ну как бы странно, что вылетает с Segmentation fault. Вот мой код.

            main.cpp
            #include <QCoreApplication>
            #include <string>
            #include <iostream>
            #include <QDebug>
            
            using namespace std;
            
            #include "reversestring.h"
            
            void codeStringView(string data)
            {
                // Вывести кодированную строку
                // полученную от callback функции
                cout << data << endl;
            }
            
            int main(int argc, char *argv[])
            {
                QCoreApplication a(argc, argv);
            
                string data;
            
                cout << "Enter string:" << endl;
            
                cin >> data;
            
                ReverseString *codeString = new ReverseString();
            
                // Установить функцию обратного вызова
                codeString->setCallBackFunc(codeStringView);
            
                codeString->decode(data);
            
                getchar();
            
                return a.exec();
            }
            reversestring.h
            #ifndef REVERSESTRING_H
            #define REVERSESTRING_H
            
            #include <map>
            #include <string>
            using namespace std;
            
            class ReverseString
            {
            public:
                ReverseString();
                ~ReverseString();
                // Получить буквенный шифр и перекодировать в цифровой
                void decode(const string data);
                // Установка функции обратного вызова
                void setCallBackFunc(void (*func) (string data));
            
            private:
                // Список численных значений для букв
                map<char, int> m_map;
                // Возвращаемая строка
                string m_string;
                // Указатель на функцию обратного вызова (возвращает цифровой шифр)
                void (*callbackfunction) (string data);
            };
            
            #endif // REVERSESTRING_H
            reversestring.cpp
            #include "reversestring.h"
            
            ReverseString::ReverseString()
            {
                // Перевод букв (шеснадцатеричные значения) в десятичные
                m_map = {{'A', 10 }, {'B', 11}, {'C', 12}, {'D', 13}, {'E', 14}, {'F', 15}};
            }
            
            ReverseString::~ReverseString()
            {
                // Очистить данные
                m_map.clear();
                m_string.clear();
            }
            
            void ReverseString::decode(const string data)
            {
                // Получить буквенный шифр и перекодировать в цифровой
                m_string.clear();
                // Прекодировка
                for (int i = 0; i < data.length(); ++i) {
                    m_string.append(to_string(m_map.at(data.at(i))));
                }
                // Вызвать функцию обратного вызова для возврата
                // кодированной строки
                callbackfunction(m_string);
            }
            
            void ReverseString::setCallBackFunc(void (*func) (string data))
            {
                // Установка функции обратного вызова
                callbackfunction = func;
            }
              Arrow
              • May 2, 2017, 11:29 p.m.

              Понял, спасибо!

              Вылетало потому, что было так:

              codeString->decode(data);
              codeString->setCallBackFunc(codeStringView);

              А нужно так:

              codeString->setCallBackFunc(codeStringView);
              codeString->decode(data);

              Туплю.

                Comments

                Only authorized users can post comments.
                Please, Log in or Sign up
                Ua

                Qt - Test 001. Signals and slots

                • Result:84points,
                • Rating points4
                Ua

                Qt - Test 001. Signals and slots

                • Result:42points,
                • Rating points-8
                ОК

                Qt - Test 001. Signals and slots

                • Result:47points,
                • Rating points-6
                Last comments
                ИМ
                Игорь МаксимовNov. 22, 2024, 9:51 p.m.
                Django - Tutorial 017. Customize the login page to Django Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
                Evgenii Legotckoi
                Evgenii LegotckoiOct. 31, 2024, 11:37 p.m.
                Django - Lesson 064. How to write a Python Markdown extension Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
                A
                ALO1ZEOct. 19, 2024, 5:19 p.m.
                Fb3 file reader on Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
                ИМ
                Игорь МаксимовOct. 5, 2024, 4:51 p.m.
                Django - Lesson 064. How to write a Python Markdown extension Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
                d
                dblas5July 5, 2024, 8:02 p.m.
                QML - Lesson 016. SQLite database and the working with it in QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
                Now discuss on the forum
                f
                firstlunoxodFeb. 15, 2025, 1:46 p.m.
                Рисование на QGraphicsScene при зажатой кнопке мыши Подскажите, пожалуйста! Как данный класс можно дополнить, чтобы созданные объекты можно было перемещать мышкой по сцене?
                Дмитрий
                ДмитрийFeb. 3, 2025, 4:24 p.m.
                Создание deb-пакета. Как создать ярлык на рабочем столе после установки собственного deb-пакета? Всем привет. Сделал свой deb-пакет с программой. Всё устанавливается и работает. Ставлю по пути /usr/bin/my_application. Как для пользователя при установке пакета сразу создать ярлык на раб…
                NW
                Nayo WaiJan. 30, 2025, 7:22 p.m.
                не запускается компьютер!!! Не запускается компьютер (точнее работает блок , но сам монитор вообще жесть)В общем я ничего с интернета не скачивала в последнее время. На компе никаких левых пр…
                n
                nklyJan. 3, 2025, 12:52 p.m.
                Нужно запретить перемещение только некоторых итемов, остальные перемещать можно. Вопрос решен. Узнать QModelIndex элемента на который мы перетаскиваем другой элемент, можно с помощью функции indexAt(event->position().toPoint()) представления QTreeViev вызываемой в переопр…
                M
                MarselAug. 17, 2023, 12:26 a.m.
                OAuth2.0 через VK, получение email Спасибо большое за помощь и простите за то что отнял время своей невнимательностью.

                Follow us in social networks