通过函数指针传递参数时获取垃圾数据”

Getting garbage data when passing a parameter through function pointer"

我正在使用函数指针将参数传递给函数。出于某种原因,当我传入它时(ClassA::parseData 的输出),我得到了垃圾数据。我正在分配 int 以将其保存在堆中,以便确保问题不是堆栈被清除,这就是变量不存在的原因。但是,这并没有解决问题。我试过按值、引用和指针传递 int,但我总是得到垃圾数据。我做错了什么?

ClassA.h

class ClassA
{
public:
    ClassA();
    ~ClassA();
    void setFunctionPointers();
    void parseData(int* dataBuffer);
};

ClassA.cpp

ClassB aClassB;

ClassA::ClassA(){}

ClassA::~ClassA(){}

void ClassA::setFunctionPointers(){
    aClassB.startTheThread((void (*)(int*)) &ClassA::parseData);
}

void ClassA::parseData(int* data){
    printf ("data received: %d \n", *data);
}

ClassB.h

class ClassB
{
    public:
        ClassB();
        ~ClassB();
        void* dataReader(void*);
        void startTheThread(void (*parseFunction)(int*));
        void (*_theParseFunction)(int*);
        pthread_t _theDataReaderThread;
};

ClassB.cpp

int* intPointer;

ClassB::ClassB(){}

ClassB::~ClassB(){
    delete intPointer;
}

void* ClassB::dataReader(void*){
    intPointer = new int;
    *intPointer = 5;
    while (true){
        _theParseFunction(intPointer);
        sleep(2);
    }
}

void ClassB::startTheThread(void (*parseFunction)(int*)){
    _theParseFunction = parseFunction;

    int threadReturn = pthread_create(&_theDataReaderThread,
                                      NULL,
                                     (void* (*)(void*)) &ClassB::dataReader,
                                      this);
}

主要方法

int main()
{
    ClassA aClassA = ClassA();
    aClassA.setFunctionPointers();

    while(true)
    {

    }

    return 0;
}

问题出在这些行上:

aClassB.startTheThread((void (*)(int*)) &ClassA::parseData);
...
pthread_create(&_theDataReaderThread,
                                      NULL,
                                     (void* (*)(void*)) &ClassB::dataReader,
                                      this);

这些是无效的类型转换。您不能像这样将非静态方法指针转换为函数指针。 pthread_create() 需要独立函数或仅 class 静态方法。

如果您使用的是 C++11 或更高版本,请试试这个:

ClassA.h

class ClassA
{
public:
    ClassA();
    ~ClassA();
    void setFunctionPointers();
    void parseData(int* dataBuffer);
};

ClassA.cpp

#include "ClassB.h"

ClassB aClassB;

ClassA::ClassA(){}

ClassA::~ClassA(){}

void ClassA::setFunctionPointers(){
    aClassB.startTheThread( [this](int *dataBuffer){ this->parseData(dataBuffer); } );
}

void ClassA::parseData(int* data){
    std::cout << "data received: " << *data << "\n";
}

ClassB.h

#include <functional>
#include <pthread.h>

class ClassB
{
public:
    using ParseFunction = std::function<void(int*)>;
    ClassB();
    ~ClassB();
    static void* dataReader(void*);
    void startTheThread(ParseFunction parseFunction);
    ParseFunction _theParseFunction;
    pthread_t _theDataReaderThread;
};

ClassB.cpp

int* intPointer;

ClassB::ClassB(){}

ClassB::~ClassB(){
    delete intPointer;
}

void* ClassB::dataReader(void *arg){
    ClassB *pThis = static_cast<ClassB*>(arg);
    intPointer = new int(5);
    while (true){
        pThis->_theParseFunction(intPointer);
        sleep(2);
    }
}

void ClassB::startTheThread(ParseFunction parseFunction){
    _theParseFunction = std::move(parseFunction);

    int threadReturn = pthread_create(&_theDataReaderThread,
                                    NULL,
                                    &ClassB::dataReader,
                                    this);
}

主要方法

int main()
{
    ClassA aClassA = ClassA();
    aClassA.setFunctionPointers();

    while(true)
    {

    }

    return 0;
}

虽然,你真的应该使用 std::thread 而不是 pthread_create():

ClassA.h

class ClassA
{
public:
    ClassA();
    ~ClassA();
    void setFunctionPointers();
    void parseData(int* dataBuffer);
};

ClassA.cpp

#include "ClassB.h"

ClassB aClassB;

ClassA::ClassA(){}

ClassA::~ClassA(){}

void ClassA::setFunctionPointers(){
    aClassB.startTheThread( [this](int *dataBuffer){ this->parseData(dataBuffer); } );
}

void ClassA::parseData(int* data){
    std::cout << "data received: " << *data << "\n";
}

ClassB.h

#include <functional>
#include <thread>

class ClassB
{
public:
    using ParseFunction = std::function<void(int*)>;
    ClassB();
    ~ClassB();
    void dataReader();
    void startTheThread(ParseFunction parseFunction);
    ParseFunction _theParseFunction;
    std::thread _theDataReaderThread;
};

ClassB.cpp

int* intPointer;

ClassB::ClassB(){}

ClassB::~ClassB(){
    delete intPointer;
}

void ClassB::dataReader(){
    intPointer = new int(5);
    while (true){
        _theParseFunction(intPointer);
        sleep(2);
    }
}

void ClassB::startTheThread(ParseFunction parseFunction){
    _theParseFunction = std::move(parseFunction);
    _theDataReaderThread = std::thread([this](){ this->dataReader(); });
}

主要方法

int main()
{
    ClassA aClassA = ClassA();
    aClassA.setFunctionPointers();

    while(true)
    {

    }

    return 0;
}

但是,如果您使用的是 C++11 之前的编译器,则必须改用普通的指向成员函数的指针:

ClassA.h

class ClassA
{
public:
    ClassA();
    ~ClassA();
    void setFunctionPointers();
    void parseData(int* dataBuffer);
};

ClassA.cpp

#include "ClassB.h"

ClassB aClassB;

ClassA::ClassA(){}

ClassA::~ClassA(){}

void ClassA::setFunctionPointers(){
    aClassB.startTheThread(&ClassA::parseData, this);
}

void ClassA::parseData(int* data){
    std::cout << "data received: " << *data << "\n";
}

ClassB.h

#include <pthread.h>

class ClassA;

class ClassB
{
public:
    typedef void (ClassA::*ParseFunction)(int*);
    ClassB();
    ~ClassB();
    static void* dataReader(void*);
    void startTheThread(ParseFunction parseFunction, ClassA*);
    ParseFunction _theParseFunction;
    ClassA *_theParseObj;
    pthread_t _theDataReaderThread;
};

ClassB.cpp

int* intPointer;

ClassB::ClassB(){}

ClassB::~ClassB(){
    delete intPointer;
}

void* ClassB::dataReader(void *arg){
    ClassB *pThis = static_cast<ClassB*>(arg);
    intPointer = new int(5);
    while (true){
        pThis->_theParseObj->*(pThis->_theParseFunction)(intPointer);
        sleep(2);
    }
}

void ClassB::startTheThread(ParseFunction parseFunction, ClassA *parseObj){
    _theParseFunction = parseFunction;
    _theParseObj = parseObj;

    int threadReturn = pthread_create(&_theDataReaderThread,
                                    NULL,
                                    &ClassB::dataReader,
                                    this);
}

主要方法

int main()
{
    ClassA aClassA = ClassA();
    aClassA.setFunctionPointers();

    while(true)
    {

    }

    return 0;
}