【问题标题】:Using SWIG typemaps to generate overloaded Python wrapper使用 SWIG 类型映射生成重载的 Python 包装器
【发布时间】:2015-06-26 17:42:59
【问题描述】:

我正在使用 SWIG 为一个用 C++ 编写的库(我们称之为 Spam)生成 Python 绑定。该库在内部定义了自己的 Vector 数据类型,在 Spam::Vector 类中定义。

考虑包装以下函数:

void ham(Spam::Vector &vec_in, Spam::Vector &vec_out);
void eggs(Spam::Vector &vec_in, double arg2, double result);

我希望能够使用 Python 列表 AND NumPy 数组作为输入来调用这些函数(而不必在 Python 中创建 Spam::Vector 对象,然后使用相关的 C++ 方法填充它- 这是非常unpythonic)。

我将如何编写 SWIG 类型图来实现这一点?此外,有没有办法为此目的合并/利用numpy.i

【问题讨论】:

  • 你的 vec_in 参数是 const 吗?还有Spam::Vector 内部是什么样子的?这将影响如何最好地包装它。
  • 是的,vec_in 是不变的。由于该库是专有的,因此没有关于 Spam::Vector 内部外观的信息。我只能访问DLLs
  • 好的,但是它是否有一个构造函数,例如接受一个指针和一个数组大小?没有它,就不可能知道如何将它与 numpy 接口。
  • 是的,它有一个将大小作为输入的构造函数。但我认为你错过了我的问题的重点。我可以弄清楚包装细节,但是我需要知道如何确保该函数能够接受 Python 列表或 Numpy 数组(或任何其他 2 种类型)的参数。我想编写可以动态检测参数“类型”并根据需要进行适当转换的包装器。
  • 我明白这一点,但我希望写一个对这两种情况都有效的答案。我将只写一个简短的答案,概述原则并跳过具体内容。

标签: python numpy wrapper swig overloading


【解决方案1】:

正确的方法是使用自定义类型映射。确切地说,这在很大程度上取决于类型 Spam::Vector 本身。一般来说,虽然你可以这样做:

%typemap(in) {
  // Maybe you'd rather check for iterable here, with this check after numpy?
  if (PyList_Check($input)) {
    $1 = ... // Code to iterate over a list and prepare a Spam::Vector
  }
  else if (PyType_IsSubtype($input->ob_type, NumpyType)) {
    $1 = ... // Code to convert from numpy input
  }
  else {
    // code to raise an error
  }
}

在其他更具体的情况下可能会出现各种黑客攻击,但这是通用的解决方案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-25
    • 1970-01-01
    • 2019-01-09
    • 1970-01-01
    • 1970-01-01
    • 2016-07-25
    • 1970-01-01
    相关资源
    最近更新 更多