2

この質問に最適なタイトルがあるかどうかはわかりません。自由に改善してください。

私が持っている場合

typedef void (*VoidFunction)(void);

そして、このタイプに適合する一連の関数として、次のような一種の「トランザクション」ラッパー関数を作成できます。

void doTransaction(VoidFunction function)
{
    doSomePreambleWork();
    function();
    doSomePostambleWork();
}

単一の int 引数を取る関数のファミリがある場合、次のように洗って、洗って、繰り返すことができます。

typedef void (*VoidOneIntFunction)(int a);
void doTransactionOneInt(VoidFunctionOneInt function, int a)
{
    doSomePreambleWork();
    function(a);
    doSomePostambleWork();
}

戻り値の型の問題を残して (つまり、戻り値の型が void であると仮定して)、このパターンをジェネリック化することは可能で、次のような 1 つのラッパー関数を記述するだけで済みます。

// ????? I'm not sure how i'd type the passed function
void doTransactionGeneric(void * function, ...)
{
    doSomePreambleWork();
    function(); // ????? and i don't know how i'd go about calling it...
    doSomePostambleWork();
}
4

3 に答える 3

2

variadic parameters...と呼ばれる構文を使用する場合は、 を使用してパラメーター リストにアクセスします。va_list

#include <stdarg.h>

typedef void (*VoidArgsFunction)(va_list args);

void doTransactionGeneric(VoidArgsFunction function, ...)
{
    doSomePreambleWork();

    va_list args;
    va_start(args, function);
    function(args);
    va_end(args);

    doSomePostambleWork();
}

呼び出された関数の内部では、必要に応じてva_arg()から個々のパラメーター値にアクセスするために使用できます。va_list

#include <stdarg.h>

void someFunction(va_list args)
{
    int param1 = va_arg(args, int);
    char *param2 = va_arg(args, char*);
    ...
}

doTransactionGeneric(&somefunction, 12345, "Hello World");
于 2013-04-24T17:36:37.107 に答える
0

ここに提案があります。

いくつかの機能があると仮定します(質問のように):

typedef void (*VoidFunction)(void);
typedef void (*VoidFunctionOneInt)(int);
// we can add more

型列挙を定義しましょう (列挙を使用する必要はありませんが、これはよりわかりやすいです)。

typedef enum
{
   e_fn_void,     // void return, no args
   e_fn_void_int, // void return, one int
                  // we can add more...
} void_function_kind_t;

次に、汎用プロセッサがあるとしましょう。関数の型、関数ポインタ、および引数を指定する必要があります。

void some_generic_function(void_function_kind_t kind, void *fn, ...)
{
   va_list args;
   va_start(args, fn);

   // here - make a call
   switch (kind)
   {
   case e_fn_void:
        // no arguments
        ((VoidFunction)fn)();
        break;
   case e_fn_void_int:
        {
           int arg0 = va_arg(args,int);
           ((VoidFunctionOneInt)fn)(arg0);
        }
        break;
   default: // error - unsupported function type
        break;
   }

   va_end(args);
}
于 2013-04-24T17:43:40.927 に答える
0

渡された関数をどのように入力するかわかりません

他の場所で関数ポインターを宣言するのと同じように:

void doTransactionGeneric(void (*function)(void), ...)

どうやって呼んだらいいのかわからない…

すでに行ったように:

function();
于 2013-04-24T17:27:47.960 に答える