![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Наверное вы знаете, что в юниксе есть такой системный вызов execv(), который выполняет нужный файл с произвольным списком параметров. Вот таким макаром:
А мне нужно нечто похожее, но чтобы вызвать функцию (по указателю) с произвольным списком аргументов. Что-то вроде:int execv(const char *path, char *const argv[]);
Функция определена где-то как обрабатывающая фиксированный набор параметров. К примеру, это может быть:void call(void (*func)(...), int *argv[]);
У меня есть указатель на функцию, и массив параметров, количество которых заранее не фиксировано. Хотелось бы вызвать некую функцию call(), которая бы положила нужные параметры на стек и вызвала функцию:void add(int *a, int *b, int *c)
{
*c = *a + *b;
}
Может такое есть уже где-то, а я просто не в курсе?call(func, argv);
no subject
Date: 2021-02-12 07:04 (UTC)https://en.cppreference.com/w/c/variadic
Статья про С++, но это сишные штуки.
no subject
Date: 2021-02-12 08:16 (UTC)no subject
Date: 2021-02-12 07:26 (UTC)no subject
Date: 2021-02-12 07:36 (UTC)откуда call усзнает размер массива argv?
если предполагается что все элементы ненулевые то примерно так:
no subject
Date: 2021-02-12 08:19 (UTC)Добавить третий параметр:
call(func, argc, argv);
switch решает задачу, но ограничивает максимальное значение argc. Да и громоздко выходит, если параметров может набежать несколько сотен.
no subject
Date: 2021-02-12 07:55 (UTC)no subject
Date: 2021-02-12 08:24 (UTC)no subject
Date: 2021-02-12 08:06 (UTC)Возможно, примерно этого самого может достигнуть сочетание alloca(), копирования правильным способом, и вызова функции без аргументов, плюс-минус несколько ассемблерных команд. Но всегда есть риск, что полученный трюк работает только на данном конкретном ABI, и сломается при первом же удобном случае.
no subject
Date: 2021-02-12 08:23 (UTC)no subject
Date: 2021-02-12 08:39 (UTC)no subject
Date: 2021-02-12 11:47 (UTC)Если типы известны, то некрасивое, но простое и портабельное решение - сделать свитч, и в нем в явном виде вызвать все разумно возможные варианты.
no subject
Date: 2021-02-12 08:18 (UTC)no subject
Date: 2021-02-12 08:21 (UTC)no subject
Date: 2021-02-12 08:31 (UTC)no subject
Date: 2021-02-12 09:52 (UTC)Какова однородность типов аргументов?
Какую проблему решаем?
А то можно же было бы в самом простом случае собирать аргументы в массив и евоный адрес передавать.
А массив – можно фиксированного размера, а можно через malloc(). А можно и VLA (хотя, лучше избегать).
Через ... и va_arg() тоже можно. Даже разнообразное.
Но нужно или число аргументов, или признак конца, или ещё что-то, если нет фиксированной схемы.
А можно ещё прикол типа чтобы функция возвращала указатель на функцию... Тогда можно паровозик с вагончиками: f(1)(2)(3)(4). Но это больше для прикола. Разницы между разделением запятыми и скобками не много.
Ещё были трюк, где макрос считал число аргументов.
Занятные вещи, которые могут не пригодится, на пофантазировать:
https://en.cppreference.com/w/c/language/generic
https://en.cppreference.com/w/c/language/compound_literal
no subject
Date: 2021-02-12 10:45 (UTC)грёбаный хтмл не даёт вставить кусок с темплейтами, но там не очень много кода
https://github.com/norian-n/WorkBox/blob/master/workbox.h
no subject
Date: 2021-02-12 10:59 (UTC)Можно выпендритсья и поддерживать таблицу динамически, но это уже перебор.