3

Cでの設計の質問に問題があります。

引数の数が異なる、かなりの数の関数があるとしましょう。

POQ:

int print_one(int x)
{
    printf("one: %d\n", x);
    return 1;
}

int print_three(int x, int y, int z)
{
    printf("three: %d-%d-%d\n", x, y, z);
    return 3;
}

ここで、いくつかのプロパティを構造内のこれらの関数に接続して、パラメーター数を含む正確な関数を知らなくてもそれらを操作できるようにします(構造インターフェイスと呼ぶこともあります)

私はそれをこのように試しました(そして私はかなり間違っていると思います):

typedef int (*pfunc)(int c, ...);

typedef struct _stroffunc
{
    pfunc myfunction;
    int flags;
    int some_thing_count;
    int arguments[10];
    int argumentcount;
} stroffunc;

int main()
{
    stroffunc firststruct;

    firststruct.pfunc = (pfunc) print_two;
    firststruct.something_count = 101;
    arguments[0] = 102;
    argumentcount = 1;
    flag &= SOME_SEXY_FLAG;

    // now I can call it, in a pretty ugly way ... however I want (with patially random results ofc)
    firststruct.pfunc(firststruct.arguments[0]);
    firststruct.pfunc(firststruct.arguments[0], 124, 11);
    firststruct.pfunc(1, firststruct.arguments[0], 124, 1, 1);
}

この解決策は非常に醜いものだと思います。関数ポインタを呼び出して設定するためのより良い解決策があると思います(願っています)。

十分に明確であることを願っています...注:このコードはコンパイルしませんでしたが、非常によく似たコードをコンパイルして実行したため、概念は機能しています。注:純粋なCが必要

4

3 に答える 3

1

可変個引数関数ポインターを介して非可変個引数関数を呼び出すと、未定義の動作が発生します。まず、可変個引数関数への引数がデフォルトの引数昇格charsはsに変換されるなど)を受けることを思い出してくださいint。これは物事を完全に台無しにします。

引数の数が異なる関数を動的に呼び出す方法や理由は明確ではありません。しかし、1つの解決策は、ユニオンを使用することです。

typedef struct {
    int num_args;
    union {
        void (*f1)(int);
        void (*f2)(int, int);
        void (*f3)(int, int, int);
    } func;
} magic;


...

magic m;
...
switch (m.num_args) {
case 1: m.func.f1(arg1); break;
case 2: m.func.f2(arg1, arg2); break;
case 3: m.func.f3(arg1, arg2, arg3); break;
default: assert(0);
}

2番目の解決策は、すべての関数を可変個引数として書き直すことです。

于 2012-04-16T20:32:59.103 に答える
0

たぶん、「疑似」クラスのように、構造体を処理するためのいくつかの関数を持つライブラリを追加できます。

int initFunc(int (*pfunc)(int c,...));

この関数は、POOのコンテキストのように、ポインターを構造体に保存します。構造体では、IDを使用してそれぞれを呼び出すすべての関数の「マップ」のように使用します。

これはIDを返し、それを配列に保存すると、別の関数が言います

int call(int id,int p1,...);

関数IDとパラメーターを言う場合は、どの関数が各IDであるかを確認する必要があります。

于 2012-04-16T19:56:58.617 に答える
0

これは私の知識の端にありますが、ABIの非互換性のために、関数も可変個引数にする必要があると思います。

参照:ウィキペディアの例

于 2012-04-16T19:50:47.647 に答える