如何在运行时生成函数?

Sha*_*ang 4 c++ macros operating-system c++14

我正在尝试用C++编写中断服务程序,这里有一些代码片段

void handlerProxy(int intrNo) {}

typedef void(*IntrHandler)();

IntrHandler IDT[256];
Run Code Online (Sandbox Code Playgroud)

我想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);};
}
Run Code Online (Sandbox Code Playgroud)

问题是

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

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

Chr*_*eck 5

您可以intrNo像这样制作模板参数:

template <int intrNo>
void handlerProxy() {}

typedef void(*IntrHandler)();
Run Code Online (Sandbox Code Playgroud)

并使用包扩展初始化数组:

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();
Run Code Online (Sandbox Code Playgroud)

(告诫者,代码未经测试)