带参数的非Void函数的Void包装

Void Wrappers for Nonvoid Functions With An Argument

本文关键字:Void 函数 包装 参数      更新时间:2023-10-16

因此,我有以下情况:

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

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

  • 我使用他们的超时库,它提供了一个API,用于在指定时间后调用ISR,但要求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对象的向量,这些对象一次设置为相同的函数,时间不同。我想以某种方式传递到TimeoutCallbackTimeout对象调用了它。

我最初的想法是重载Timeout类,使其能够接受int函数(int)函数指针,并接受重载的attach函数中传递给所述函数指针的数字。然而,考虑到Timeout类的混乱(和特定于设备的)继承,我不确定这是否真的可行。

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

虽然Tony D的解决方案在使用mbed Ticker类时是合适的,但也有一种使用mbed RtosTimer的替代方法。

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

void handler(void const* n) 

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

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

由于您的库可以调用成员函数,因此您可以创建一个适配器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();
}