How can I use a static C++ method as a callback for a Poco timer?

人走茶凉 提交于 2020-01-06 05:25:36

问题


Particularly I'm talking about the constructor of this Poco class: Poco.TimerCallback

I would like to use it in legacy C++ code where most of the classes I've written are "static" so that they only contain static methods and no constructors, just because I won't need multiple instances of such objects anyway, and the classes are merely for encapsulation. Well yeah, the Poco guys suggest to add a callback method like this:

TimerCallback<MyClass> callback(*this, &MyClass::onTimer);
timer.start(callback);

Do I understand this code snippet correctly: MyClass::onTimer may also be a static method of MyClass, but I also need the current instance of MyClass, so that methods of static classes, which are not instantiated, are simply banned from being used as a TimerCallback, or am I wrong?

Thank you.


回答1:


I would not call it "banned" - the function callbacks are just not implemented, and there is nothing preventing you to implement it yourself (and send it back as a contribution, if you are inclined to do so).

I'd just extend the TimerTaskAdapter, so that it does not require object instance, eg. something like this:

typedef void (*FunctionCallback)(TimerTask&);
TimerTaskAdapter(FunctionCallback func): _pObject(0), _method(0), _func(func){}
...
FunctionCallback _func;

Then detect in TimerTaskAdapter::run() what is null and whether to call the method or function:

void run()
{
    if (_pObject) (_pObject->*_method)(*this);
    else (*_func)(*this);
}



回答2:


After running into a much more nasty problem (related to pointers to class members) when extending TimerTaskAdapter, someone suggested to derive my class from TimerTask directly: Pointer to member type incompatible with object type → What is the cause?

See this sourcecode:

ProceduralTimerTaskAdapter.h:

// Header file for ProceduralTimerTaskAdapter.cpp class file.
// This is an extension of the Poco::Util::TimerTask class.

#include <Poco/Util/Timer.h>
#include <Poco/Util/TimerTask.h>

#ifndef PROCEDURALTIMERTASKADAPTER_H
#define PROCEDURALTIMERTASKADAPTER_H

using namespace std;
using namespace Poco::Util;

typedef void (*Callback) (TimerTask&);

namespace Poco {
  namespace Util {
    class ProceduralTimerTaskAdapter : public TimerTask {
    public:
      ProceduralTimerTaskAdapter (Callback procedure); // Constructor

      void run (); // Method defining the main thread
    protected:
      ~ProceduralTimerTaskAdapter (); // Destructor (not for general use)
    private:
      ProceduralTimerTaskAdapter (); // Default constructor (not for general use)

      Callback procedure; // The callback procedure called by the timer.
    };
  }
}

#endif

ProceduralTimerTaskAdapter.cpp:

// This is the implementation of the ProceduralTimerTaskAdapter class.

#include <iostream>
#include <Poco/Util/Timer.h>
#include <Poco/Util/TimerTask.h>
#include "ProceduralTimerTaskAdapter.h"

using namespace std;
using namespace Poco::Util;

ProceduralTimerTaskAdapter::ProceduralTimerTaskAdapter (Callback proc) :
  TimerTask::TimerTask (),
  procedure (proc)
{
}

ProceduralTimerTaskAdapter::~ProceduralTimerTaskAdapter ()
{
}

void ProceduralTimerTaskAdapter::run ()
{
  procedure (*this);
}

It worked out of the box. Nevertheless thank you for your answers & comments!



来源:https://stackoverflow.com/questions/52132421/how-can-i-use-a-static-c-method-as-a-callback-for-a-poco-timer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!