Slardar Zhang Slardar Zhang - 4 months ago 11
C++ Question

How to generate function in runtime?

I'm trying to write Interruption Service Routine in C++, here is some code snippet

void handlerProxy(int intrNo) {}

typedef void(*IntrHandler)();

IntrHandler IDT[256];


I want to initialize
IDT
in run-time or compile-time like this:

for (size_t i = 0; i < 256; ++i) {
// It doesn't compile
IDT[i] = std::bind(handlerProxy, i);
// or
IDT[i] = [i] () {handlerProxy(i);};
}


The problem is


  • lambda function with capture can not be converted to function pointer

  • My code will be compiled with
    -fno-rtti
    , so
    std::function::target
    is not available



Is there any possibility I can manage to do this?
I don't want to write
IDT[0]= ... IDT[1]=...
manually or use other program to generate it. Macro and inline asm is allowed. Type of
IDT
can be changed, however the element of
IDT
should be function address, which means something like
jmp IDT[0]
should be valid.

Answer

You could make intrNo a template parameter like so:

template <int intrNo>
void handlerProxy() {}

typedef void(*IntrHandler)();

and initialize the array using a pack expansion:

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();

(caveat emptor, code not tested)

Comments