1

我正在尝试编写一个类型映射,将多个/可变参数转换为一个输入参数。

例如,假设我有一个带有向量的函数。

void foo(vector<int> x);

我想这样称呼它(恰好在Perl中)

foo(1,2,3,4);

typemap 应该接受参数 ($argnum, ...),将它们收集到一个向量中,然后将其传递给 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 将期望使用两个参数调用 foo。

 foo(arg1, arg2);

也许有一种方法可以告诉 SWIG 从对 foo 的调用中抑制 arg2?

我不能在我的 .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 回答