具有参数的非空函数的无效包装

时间:2015-06-29 01:57:26

标签: c++ embedded microcontroller mbed

所以,我有以下情况:

  • 我在低内存微控制器上编码mbed在线编译器。

  • 实时性能非常重要,我希望这需要不到一微秒。 10微秒是可以容忍的。

  • 我正在使用他们的超时库,它提供了在指定时间后调用ISR的API,但要求ISR是一个void / void函数。 (包括成员函数。

    void TimeoutCallback(void) { do stuff that I want to do on timeout.} // ISR
    
    Timeout to; 
    to.attach_us(&TimeoutCallback, 750) // Call TimeoutCallback in 750 us. 
    
  • 我创建了一个Timeout对象的向量,它们都被设置为同一个函数,并且具有不同的时间量。我想以某种方式传递给TimeoutCallback 哪个 Timeout对象调用它。

我最初的想法是重载Timeout类以允许它接受int函数(int)函数指针,并接受传递给所述函数指针的重载attach函数中的数字。但是,鉴于Timeout类的混乱(和特定于设备)继承,我不确定这是否实际可行。

现在,我想知道是否有一种方法以编程方式创建包含void / int函数的void / void函数,并包含一个可更改的引用int,该函数将传递给包装函数。

2 个答案:

答案 0 :(得分:1)

如果使用mbed Ticker类,Tony D的解决方案是合适的,那么使用mbed RtosTimer的替代方法。

RtosTimer构造函数接受一个void*参数,该参数在超时时传递给处理程序。处理程序具有签名:

void handler(void const* n) 

其中n是传递给构造函数的指针参数,可用于识别特定的超时。

与超时函数在中断上下文中运行的Ticker不同,对于RtosTimer,处理程序作为线程运行,因此提供了更大的灵活性,但潜在的延迟可能更大。

答案 1 :(得分:0)

由于您的库可以调用成员函数,您可以创建适配器ala ...

template <typename Func, Func func>
struct Adapter
{
    Adapter(int n) : n_(n) { }

    void f() { func(n_); }
    int n_;
};

使用它:

Adapter<void(*)(int), My_Function_Expecting_An_Int> adapter(the_int);
to.attach_us(&adapter, &decltype(adapter)::f, timeout_us);

确保adapter的生命周期一直持续到回调....

调用成员函数:

#include <iostream>
#include <string>
#include <vector>

struct MyObj
{
    void f(int n) { std::cout <<"hi " << n << "\n"; }
};

template <typename Class, typename PFunc>
struct Adapter
{
    Adapter(Class& object, PFunc pFunc, int n) : object_(object), pFunc_(pFunc), n_(n) { }

    void f() { (object_.*pFunc_)(n_); }

    Class& object_;
    PFunc pFunc_;
    int n_;
};

int main()
{
    MyObj myObj;

    Adapter<MyObj, void(MyObj::*)(int)> adapter(myObj, &MyObj::f, 43);
    adapter.f();
}