Назначьте сохраненную функцию для create_thread - PullRequest
0 голосов
/ 28 апреля 2020

Я создал класс CThread, который должен быть базовым классом для многих других классов и содержать код, связанный с потоками.

В CThread У меня есть переменная:

int (*m_fpRun)() = 0;

Здесь CThread наследуется классом CTemp, а m_fpRun назначена процедура CTemp::Run()

Я пытался присвоить функции

iRetVal = pthread_create(&m_sThreadID,
                         m_pAttr,
                         &m_fpRun,
                         m_pArg);

Но я всегда получаю эту ошибку :

error: cannot convert ‘int (**)()’ to ‘void* (*)(void*)’ for argument ‘3’ to ‘int pthread_create(pthread_t*, const pthread_attr_t*, void* (*)(void*), void*)’
                            m_pArg);

Ответы [ 2 ]

0 голосов
/ 28 апреля 2020

Ваш компилятор верен :-)

3-й аргумент pthread_create равен void * (*)(void *) (указатель на функцию, принимающую указатель на void в качестве параметра и возвращающую указатель на void)

Ваш аргумент имеет тип int (**)() (указатель на указатель на функцию, не принимающий ничего в качестве параметра и возвращающий int)

В двух словах: нет способа преобразовать значение в указатель для возвращаемого типа и никоим образом не преобразовать ничто в указатель для void для аргумента.

Вы должны изменить m_pfRun.

0 голосов
/ 28 апреля 2020

Короче говоря, вы не можете делать то, что вы пытаетесь. Ваша переменная m_fpRun просто неправильного типа для того, что ожидает pthread_create(). И если бы это был правильный тип, то вы не могли бы присвоить ему метод класса non-stati c.

Короче говоря, вы просто не можете использовать non -stati c метод класса в качестве обратного вызова pthread. Вам нужно использовать промежуточную автономную функцию или stati c метод класса, и тогда он может вызывать вашу целевую функцию по мере необходимости, например:

#include <functional>

class CThread
{
private:
    pthread_t m_sThreadID;
    pthread_attr_t *m_pAttr = nullptr;

    static void* StaticRun(void *arg)
    {
        CThread *pThis = (CThread*) arg;
        int iRetVal = pThis->m_fpRun();
        ...
        return nullptr; 
    }

protected:
    std::function<int()> m_fpRun;

public:
    void Start()
    {
        int iRetVal = pthread_create(&m_sThreadID,
                                     m_pAttr,
                                     &StaticRun,
                                     this);
        ...
    }
};

class CTemp : public CThread
{
private:
    int Run()
    {
        ...
    }

public:
    CTemp()
    {
        m_fpRun = [this](){ return this->Run(); };
    }
};

В качестве альтернативы, вы должны используйте метод virtual вместо переменной-указателя функции, например:

class CThread
{
private:
    pthread_t m_sThreadID;
    pthread_attr_t *m_pAttr = nullptr;

    static void* StaticRun(void *arg)
    {
        CThread *pThis = (CThread*) arg;
        int iRetVal = pThis->Run();
        ...
        return nullptr; 
    }

protected:
    virtual int Run() = 0;

public:
    void Start()
    {
        int iRetVal = pthread_create(&m_sThreadID,
                                     m_pAttr,
                                     &StaticRun,
                                     this);
        ...
    }
};

class CTemp : public CThread
{
private:
    int Run() override
    {
        ...
    }

public:
    CTemp() = default;
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...