2016-11-21 3 views
2

Я знаю, что если я принял аргумент, как void (*func)(void *) к VARIADIC функции, я могу получить аргумент вроде:C как получить аргумент типа указатель на функцию от va_arg

void (*func)(void *) = va_arg(args, void (*)(void)); 

Что делать, если я прохожу что-то вроде void (** func)(void *)? Каков правильный синтаксис для получения аргумента этого типа с использованием va_arg?

ответ

5

Будучи откровенно, ваш код не является стандартным требованиям. Существует крошечная ограничение для второго аргумента va_arg() макроса:

... Параметр type должно быть имя типа указано, что тип указателя на объект, который имеет указанный тип может быть получен просто путем постфиксации типа *. ...

В соответствии с этим, в данном случае неприемлемы обозначения void (*)(void *). Поскольку простое добавление * не даст вам указателя на указатель на функцию. Вы можете использовать только typedef -ED псевдонимами:

typedef void (*func_ptr)(void *); 
typedef void (**ptr_to_func_ptr)(void *); 

func_ptr var1 = va_arg(ap, func_ptr); 
ptr_to_func_ptr var2 = va_arg(ap, ptr_to_func_ptr); 
1

же, как вы уже упоминали:

typedef void (** func_t)(void *); 
func_t ppf; 
va_list vl; 
va_start(vl,n); 
ppf = va_arg(vl, func_t); 
... 
0

Чтобы указатель на функцию, я всегда использование typedef следующим образом:

typedef void VoidFn(void *); // Function accepts void * and returns nothing. 

Это объявляет прототип функции как typedef , что позволяет использовать typedef в другом месте.

Таким образом, если у вас есть эта функция:

void SomeFn(void *) {...} 

вы можете объявить этот указатель:

VoidFn *fnPtr = &SomeFn; // A pointer to such a function. 

Это тогда делает его легче изменить прототип независимо указателя, помогая более ... сложные конструкции:

typedef void *VoidPtrFn(void *); // Function takes a void *, returning a void * 

void *SomeOtherFn(void *) { ... } 
VoidPtrFn *otherFnPtr = &SomeOtherFn; 
VoidPtrFn **otherFnPtrPtr = &otherFnPtr;