web-dev-qa-db-ja.com

va_listに記入するにはどうすればよいですか

Va_listがある場合、そのすべての要素を抽出する方法を知っています。

void printInts(int n,...)
{
    va_list va;
    va_start(va, n);
    for(unsigned int i=0; i<n; i++)
    {
        int arg=va_arg(va, int);
        printf("%d",arg);
    }
    va_end(va);
} 

したがって、printInts(3,1,2,3)を呼び出すと、va_listにすべてのパラメーターが入力されます。
しかし、va_startを使用せずにva_listを手動で入力するにはどうすればよいですか?私は次のようなものが欲しいという意味です:

va_list va;
Push_arg(va, int, 5); // And so on until I fill all parameters
...

Va_listを引数として受け入れる関数があり、そのすべてのパラメーターのva_listを埋める方法がわからないため、これが必要です。

20
Ramy Al Zuhouri

Va_listを明示的に入力する機能はありません。

ラッパー関数を作成する必要があります。 va_listを手動で入力する代わりに、関数fooを呼び出す必要があるとすると、次のように新しい関数を定義します。

void call_foo(int arg1, ...)
{
   va_list ap;
   va_start(ap, arg1);
   foo(arg1, ap);
   va_end(ap);
}

これで、fooを呼び出すことができます。これは、va_listを取得しますが、たとえば、 call_foo(1,2,3,4);、 call_foo(1、1、 "Hello");等.

これにより、コンパイル時にのみ引数を指定でき、実行時に引数を作成することはできません。

19
nos

通常、これらの関数はペアで提供されます。 「va-accepting」関数がある場合は、別の関数を簡単に作成できます。

void printInts_v(int n, va_list ap)
{
    unsigned int i=0;
    for(i=0; i<n; i++)
    {
        int arg=va_arg(ap, int);
        printf("%d", arg);
    }
}

この関数は次のように呼び出すことができます。

void printInts(int n,...)
{
    va_list ap;
    va_start(ap, n);
    printInts_v(n, ap);
    va_end(va);
}

しかし、後で使用するためにva_listを移植可能に事前入力する方法はないと思います。

1つのアーキテクチャで作業していて、移植性が問題にならない場合は、自分で何かを作成することもできます。これを正確に行う方法は、プラットフォームによって異なります。

11
glglgl

他の返信はそれが不可能であると言っているので(これは次のバージョンの言語の設計にそれを追加するのに十分な理由です)、唯一の移植可能な可能性は

  • ドキュメントを2回チェックして、使用しようとしているフレームワークについて何かを見逃したり誤解したりしていないかどうかを調査します。まったく同じ問題が発生しました ここ そして答えに私はそうではなかったように見えました私がやろうとしていたことに対して正しい呼びかけをすること。

  • va_listの代わりにポインターの配列をパラメーターとして受け取り、問題を複数の呼び出しに分割する関数を自分で作成する(常に可能とは限りません)。または

  • 使用しようとしているフレームワークが適切に設計されていないと仮定します...

0
Camion

これを行うための標準化された方法はないと思います。一方、そのような事前入力されたva_listは、使用可能な引数の数とタイプを「照会」する方法もないため、かなり役に立たないでしょう。

0
unwind