带参数的非空函数的空包装
Void Wrappers for Nonvoid Functions With An Argument
所以,我有以下情况:
我正在低内存微控制器上为 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 对象向量,所有对象都一次性设置为相同的函数,但时间长短不同。我想以某种方式传递给调用它的 TimeoutCallback which 超时对象。
我最初的想法是重载 Timeout class 以允许它接受 int 函数 (int) 函数指针,并在重载的附加函数中接受传递给所述函数指针的数字。但是,考虑到超时 class 的混乱(和特定于设备的)继承,我不确定这是否实际可行。
现在,我想知道是否有一种方法可以通过编程方式创建一个包装 void/int 函数的 void/void 函数,并包含一个传递给包装函数的可变引用 int。
由于您的库可以调用成员函数,因此您可以创建一个适配器...
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();
}
虽然 Tony D 的解决方案在使用 mbed Ticker
class 时是合适的,但还有一种使用 mbed RtosTimer
.
的替代方法
RtosTimer
构造函数采用 void*
参数,该参数在超时时传递给处理程序。处理程序具有签名:
void handler(void const* n)
其中 n
是传递给构造函数的指针参数,可用于标识特定超时。
与超时函数在中断上下文中运行的 Ticker
不同,对于 RtosTimer
处理程序作为线程运行,因此提供了更大的灵活性,但可能会有更大的延迟。
所以,我有以下情况:
我正在低内存微控制器上为 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 对象向量,所有对象都一次性设置为相同的函数,但时间长短不同。我想以某种方式传递给调用它的 TimeoutCallback which 超时对象。
我最初的想法是重载 Timeout class 以允许它接受 int 函数 (int) 函数指针,并在重载的附加函数中接受传递给所述函数指针的数字。但是,考虑到超时 class 的混乱(和特定于设备的)继承,我不确定这是否实际可行。
现在,我想知道是否有一种方法可以通过编程方式创建一个包装 void/int 函数的 void/void 函数,并包含一个传递给包装函数的可变引用 int。
由于您的库可以调用成员函数,因此您可以创建一个适配器...
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();
}
虽然 Tony D 的解决方案在使用 mbed Ticker
class 时是合适的,但还有一种使用 mbed RtosTimer
.
RtosTimer
构造函数采用 void*
参数,该参数在超时时传递给处理程序。处理程序具有签名:
void handler(void const* n)
其中 n
是传递给构造函数的指针参数,可用于标识特定超时。
与超时函数在中断上下文中运行的 Ticker
不同,对于 RtosTimer
处理程序作为线程运行,因此提供了更大的灵活性,但可能会有更大的延迟。