我正在尝试用C ++编写中断服务程序,这里有一些代码片段
void handlerProxy(int intrNo) {}
typedef void(*IntrHandler)();
IntrHandler IDT[256];
我想在运行时或编译时初始化IDT
,如下所示:
for (size_t i = 0; i < 256; ++i) {
// It doesn't compile
IDT[i] = std::bind(handlerProxy, i);
// or
IDT[i] = [i] () {handlerProxy(i);};
}
问题是
-fno-rtti
进行编译,因此std::function::target
不可用我有可能设法做到这一点吗?
我不想手动编写IDT[0]= ... IDT[1]=...
或使用其他程序来生成它。允许宏和内联asm。 IDT
的类型可以更改,但IDT
的元素应该是函数地址,这意味着jmp IDT[0]
之类的内容应该有效。
答案 0 :(得分:5)
您可以将intrNo
设为模板参数,如下所示:
template <int intrNo>
void handlerProxy() {}
typedef void(*IntrHandler)();
并使用包扩展来初始化数组:
template <typename IS>
struct helper;
template <size_t ... Is>
struct helper<std::index_sequence<Is...>> {
static constexpr std::array<IntrHandler, sizeof...(Is)> make_handlers() {
return {{ &handler_proxy<Is> ... }};
}
};
constexpr std::array<IntrHandler, 256> IntrHandlers = helper<std::make_index_sequence<256>>::make_handlers();
IntrHandler * IDT = IntrHandlers.data();
(警告,未经测试的代码)
答案 1 :(得分:1)
Chris的答案更紧凑,但这可以通过元组完成,将handlerProxy定义为带有静态成员的模板化函数对象:
template <int i>
struct handlerProxy{
static int func(){return i * i;}
};
然后函数创建指向函数的指针元组:
template <size_t... I>
decltype(auto) functions(std::index_sequence<I...>) {
return return std::make_tuple(&handlerProxy<I>::func...);
}
template <size_t size>
decltype(auto) generate_functions() {
using Indices = std::make_index_sequence<size>;
return functions(Indices{});
}
使用:
int main()
{
//generate tuple of functions
auto IDT = generate_functions<256>();
//call 2th function
std::cout << std::get<2>(IDT)();
}
注意:gcc中的-ftemplate-depth选项应设置为相对较大的数字,50000,以便编译