0

未使用のANSIC(1989)の1つの問題を解決する必要があります。

(int n)doubleパラメーターで機能するためのポインター(void * func)があり、数値の配列double values[]がありnます。nそのため、valueにあるparamを使用して関数を実行したいと思います。

たとえば、次の関数があります。

double hypotenuse(double x, double y, double z);

それで

void *func = (void *)hypotenuse; double values[3] = {5, 4, 3}; int n = 3;

そして私はこのようなことをしたい:

func(n, values);

問題は、関数のプロトタイプを変更できないことです。そのため、これを何らかの方法で行う必要があります(おそらくいくつかのマクロ?)。

4

2 に答える 2

4

主な問題は、引数の数に応じて (つまり、n変数に応じて) ポインターを異なる方法でキャストする必要があることです。

switch1 つの方法は、引数番号のステートメントを含むラッパー関数を使用することです。

double wrapper(void *func, double args[], int n)
{
    switch (n)
    {
    case 0:
        return ((double (*)(void)) func)();
    case 1:
        return ((double (*)(double)) func)(args[0]);
    case 2:
        return ((double (*)(double, double)) func)(args[0], args[1]);
    case 3:
        return ((double (*)(double, double, double)) func)(args[0], args[1], args[2]);
    default:
        printf("Error: wrapper called with %d arguments\n", n)
        break;
    }

    return 0.0;
}
于 2013-02-15T08:09:36.900 に答える
2

昨夜遅くに書きましたが、投稿しようとしたときにインターネット接続がダウンしました。ヨアヒムが本質的に同じ答えを書いているのがわかります。


制限内で、これは機能します:

#include <assert.h>

extern double function_invoker(void *func, int n, double *values);

double function_invoker(void *func, int n, double *values)
{
    switch (n)
    {
    case 0:
        return (*(double (*)(void))func)();
    case 1:
        return (*(double (*)(double))func)(values[0]);
    case 2:
        return (*(double (*)(double, double))func)(values[0], values[1]);
    case 3:
        return (*(double (*)(double, double, double))func)(values[0], values[1], values[2]);
    default:
        assert("Need more entries in the switch in function_invoker()" == 0);
        return(0.0);
    }
}

明らかな制限は、 に作成するエントリの数ですswitch。大まかに類似したコードが 100 を超える引数になるのを見てきました。なぜそれが必要だと考えられたのかはわかりません。

このコードは、Mac OS X 10.8.2 の GCC 4.6.0 で警告なしにコンパイルされます。

$ gcc -g -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
    -Wold-style-definition -c x.c
$

しかしdouble (*)()、代わりに を使用すると、次のvoid *ようになります。

$ gcc -g -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
    -Wold-style-definition -c x.c
x.c:3:1: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
x.c:5:1: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
$
于 2013-02-15T15:52:51.970 に答える