1

複数/可変引数を 1 つの入力パラメーターに変換する typemap を作成しようとしています。

たとえば、ベクトルを受け取る関数があるとします。

void foo(vector<int> x);

そして、私はそれをこのように呼びたいです(たまたまPerlにあります)

foo(1,2,3,4);

typemap は引数 ($argnum, ...) を取り、それらを 1 つのベクトルに集めてから、それを foo に渡す必要があります。

私はこれまでのところこれを持っています:

typedef vector<int> vectori;
%typemap(in) (vectori) {
  for (int i=$argnum-1; i<items; i++) {
      $1->push_back( <argv i> );   // This is language dependent, of course.
  }
}

SWIGが引数の数をチェックすることを除いて、これは機能します

if ((items < 1) || (items > 1)) {
  SWIG_croak("Usage: foo(vectori);");
}

私が行った場合:

 void foo(vectori, ...);

SWIG は、2 つの引数で foo を呼び出すことを期待します。

 foo(arg1, arg2);

おそらく、foo の呼び出しから arg2 を抑制するように SWIG に指示する方法はありますか?

.i でこれを使用できません:

void foo(...)

foo が期待しているタイプ (int の配列、文字列など) に応じて、異なるタイプマップが必要なためです。「...」に型を与える方法があるかもしれません。

これを行う方法はありますか?

4

2 に答える 2

2

SWIG には、いくつかの STL クラスのサポートが組み込まれています。SWIG .i ファイルでこれを試してください:

%module mymod

%{
#include <vector>
#include <string>
void foo_int(std::vector<int> i);
void foo_str(std::vector<std::string> i);
%}

%include <std_vector.i>
%include <std_string.i>
// Declare each template used so SWIG exports an interface.
%template(vector_int) std::vector<int>;
%template(vector_str) std::vector<std::string>;

void foo_int(std::vector<int> i);
void foo_str(std::vector<std::string> i);

次に、選択した言語の配列構文で呼び出します。

#Python
import mymod
mymod.foo_int([1,2,3,4])
mymod.foo_str(['abc','def','ghi'])
于 2012-06-27T03:43:51.737 に答える
0

SWIG は、SWIG がバインドを生成するときに引数の数を決定します。SWIG は可変引数リストの限定的なサポートを提供していますが、これが正しいアプローチであるかどうかはわかりません。興味がある場合は、SWIG varargドキュメント セクションで詳細を読むことができます。

これらの値を配列参照として渡す方が良いと思います。タイプマップは次のようになります (テストされていません)。

%typemap(in) vectori (vector<int> tmp)
{
    if (!SvROK($input))
        croak("Argument $argnum is not a reference.");

    if (SvTYPE(SvRV($input)) != SVt_PVAV) 
        croak("Argument $argnum is not an array.");

    $1 = &$tmp;

    AV *arrayValue = (AV*)SvRV($input);
    int arrayLen = av_len(arrayLen);

    for (int i=0; i<=arrayLen; ++i) 
    {
        SV* scalarValue = av_fetch(arrayValue , i, 0);
        $1->push_back( SvPV(*scalarValue, PL_na) );
    }
};

次に、Perl から配列表記を使用します。

@myarray = (1, 2, 3, 4);
foo(\@myarray);
于 2009-11-25T14:31:40.540 に答える