Избегайте подсчета элементов массива при вызове функции - PullRequest
0 голосов
/ 07 января 2019

Я определяю сигнатуру функции для выполнения удаленного вызова процедуры. Из-за undefined behavior я не могу увеличить индексную переменную в выражении вызова, поэтому я в итоге посчитал от 0 до последнего индекса и передал каждый из них в качестве аргумента. Есть ли более элегантный способ сделать это, не считая? Я думал о петле или о чем-то. Это пригодится, когда число фиксированных аргументов изменится, например, на 16 аргументы вместо 8.

typedef unsigned long long int functionType(int, int, int, int, int, int, int, int);

unsigned long long int call_address(uintptr_t real_address, const unsigned int *arguments) {
    auto function = (functionType *) real_address;

    // We count instead of incrementing an index variable because: operation on 'argumentIndex' may be undefined
    return function(arguments[0], arguments[1],
                    arguments[2], arguments[3],
                    arguments[4], arguments[5],
                    arguments[6], arguments[7]);
}

Я знаю, что есть переменные аргументы , использующие va_start, va_list и va_end, но я не уверен, что их можно использовать здесь.

1 Ответ

0 голосов
/ 07 января 2019

Часть вашего решения включает в себя распаковку фиксированного количества значений из вашего arguments массива и вызов function с ним. Следующий код C ++ 14 сделает это:

template <typename F, size_t... Is>
unsigned long long int our_invoke(F f, const unsigned int * args, std::index_sequence<Is...>) {
    return f(args[Is]...);
}

unsigned long long int call_address(uintptr_t real_address, const unsigned int *arguments) {
    auto function = (functionType *) real_address;

    return our_invoke(function, arguments, std::make_index_sequence<8>{});
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...