我正在尝试用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);};
}

问题是

带捕获的
  • lambda函数无法转换为函数指针
  • 我的代码将使用-fno-rtti编译,因此std::function::target不可用

  • 我有可能做到这一点吗?
    我不想手动编写IDT[0]= ... IDT[1]=...或使用其他程序生成它。允许宏和内联汇编。 IDT的类型可以更改,但是IDT的元素应为函数地址,这意味着jmp IDT[0]之类的内容应有效。

    最佳答案

    您可以像这样将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();
    

    (腔体清空器,未测试代码)

    10-06 01:03