如何在运行时生成函数

How to generate function in runtime?

本文关键字:函数 运行时      更新时间:2023-10-16

我正在尝试用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]=...,也不想使用其他程序来生成它。允许使用宏和内联asm。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();

(注意清空,代码未测试(

Chris的答案更紧凑,但是这可以用tuple来完成,将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,以编译