可视化 如何将私有数据类的成员函数作为 C++ 非托管线程的回调发送?

visual How to send Private data class's member function as a callback for a thread in c++ unmanaged?

本文关键字:C++ 线程 回调 函数 数据 可视化 成员      更新时间:2023-10-16

我有一些未加密的代码移植到VC100中。我正在尝试使用计时器每隔一段时间运行成员函数。此类使用设计模式私有类数据。我不确定如何设置回拨。我试过了

    class IProcessable {
    public:
        virtual void process() throw () = 0;
    protected:
        IProcessable() throw () {}
        virtual ~IProcessable() throw () {}
    };

class Processor::Private {
    private:
        IProcessable & mProcessable;
    public:
        Private(IProcessable & processable,
            unsigned int   interval_ms) throw () : 
            mProcessable(processable)
        {
            CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)(this->callTimer), 0, 0, NULL);
            // I want to send the callTimer to be called at the interval..
            onTimer();
        }
        __fastcall ~Private() throw () {
        }
        void callTimer()
        {
            mProcessable.process();
        }
    private:
        void __fastcall onTimer() {
            mProcessable.process();
        }
    };
    Processor::Processor(IProcessable & processable, unsigned int interval_ms) throw () :
        mPrivate(new Private(processable, interval_ms)) {}
    Processor::~Processor() throw () {
        delete mPrivate;
    } 
}

错误 C2440:"类型转换":无法从"重载函数"转换为"LPTHREAD_START_ROUTINE">

callTimer是一个

成员函数,它需要一个this上下文来知道它正在操作的类的哪个实例。

LPTHREAD_START_ROUTINE需要一个函数,该函数采用 LPVOID (void*( 参数并返回 DWORD,callTimer不带参数,也不返回。

你需要的是一个蹦床静态函数,它接受一个类实例并转发到相应的成员函数:

CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)(this->callTimerIf), (void*)this, 0, NULL);

和(这是私人的成员(:

static DWORD callTimerIf(void* instance)
{
    Private* pvt = (Processor::Private*)instance;
    pvt->callTimer();
    return 0;
}

callTimer是一个类方法。它有一个隐藏的this参数,因此如果您传递的函数看起来像

void (*) (Processor * this)

而不是

DWORD (*) (LPVOID lpThreadParameter)

所以你需要做的是这样的:

class Processor::Private {
    private:
        IProcessable & mProcessable;
    public:
        Private(IProcessable & processable,
            unsigned int   interval_ms) throw () : 
            mProcessable(processable)
        {
            CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)(&callTimer), this, 0, NULL);
            onTimer();
        }
        __fastcall ~Private() throw () {
        }
        static DWORD callTimer(LPVOID lpThreadParameter)
        {
            Private * priv = (Private *)lpThreadParameter;
            priv->mProcessable.process();
            return 0; // or whatever makes sense
        }
    private:
        void __fastcall onTimer() {
            mProcessable.process();
        }
    };

重要更改 1:

static DWORD callTimer(LPVOID lpThreadParameter)

callTimer方法现在是静态的,不需要调用任何对象。所以没有this参数。相反,this被隐藏为lpThreadParameter,并投射到Private *以调用我们真正想要调用的函数。它还与LPTHREAD_START_ROUTINE所需的原型相匹配。

重要更改 2:

CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)(&callTimer), this, 0, NULL);

传入 now-static callTimer 方法的地址,this 作为稍后将再次显示为 lpThreadParameterlpParameter

获得正确的时间是另一个问题,但是如果您要使用此体系结构,则可能需要一个可等待计时器。

其他方法仍使用可等待计时器,但通过重叠 IO 使用它,这可能有助于您使程序更易于同步。