Изменение подписи указателя функции - PullRequest
4 голосов
/ 19 мая 2011

У меня небольшая проблема, у меня есть указатель на эту функцию:

typedef void* (* funcPointer)(const void *in, int ilen, void *out, int *olen)

И эта функция

void* foo1(const void *in, int ilen, void *out, int *olen)
{
   if(CONST_VALUE_1 > iLen)
      //do something
   else
      //do something else
   return whatever;
}

Где-то в коде

// ...
funcPointer fpointer = foo1;
if(someArgument > SOME_OTHER_CONSTANT)
   // where foo2 is the same as foo1 except that it uses CONST_VALUE_2
   fpointer = foo2; 
bar( someVariable, anotherVariable, fpointer);
// ...

Как видите, в теле этой функции есть CONST_VALUE_X. Я хотел бы иметь возможность удалить константу и использовать вместо этого пятый аргумент. Поскольку я не могу изменить сигнатуру, мне было интересно, было ли что-то сделать или скопировать и вставить функцию с каждым возможным постоянным значением ...

Спасибо

Ответы [ 3 ]

1 голос
/ 19 мая 2011

Если вы не можете изменить сигнатуру функции, то, как вы говорите, у вас не будет пятого аргумента!

Я вижу три варианта:

  1. Полагаю, вы можете вставить его в один из других void * аргументов (например, определить структуру, содержащую исходное значение для in и значение "константы", а затем передать это как in).

  2. Установите глобальную переменную перед вызовом функции. Это плохая идея.

  3. Вы можете написать эту функцию в виде макроса, чтобы избежать кошмара обслуживания при копировании и вставке. Это плохая идея.

0 голосов
/ 19 мая 2011

То, что вы хотите, называется замыканием , и C не имеет явной поддержки для замыканий. Вы можете достичь того же самого, изменив свой API, чтобы он содержал указатель на функцию и указатель на аргумент вместо простого указателя на функцию. Тогда вам просто нужны версии функции: одна, которая использует явный аргумент, предоставленный вызывающей стороной, и другая, которая использует значение из указателя переносимого аргумента.

0 голосов
/ 19 мая 2011

Вы можете заменить константу чем-то, что вызывающий может временно изменить (например, глобальной переменной).

Например:

int oldLenghtLimit = LengthLimit;
... call the function ...
LengthLimit = oldLengthLimit;

А, в функции:

void* foo1(const void *in, int ilen, void *out, int *olen)
{
  if(LengthLimit > iLen)
    //do something
  else
    //do something else
  return whatever;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...