禁止通过 swig 为 python-C++ 接口生成隐式类型检查代码

Disable generation of implicit type checking code by swig for python-C++ interface

对于以下简单函数:

#include <iostream>
void Echo(int no) {
    std::cout << "no: " << no << std::endl;
}

我有以下 swig 接口文件:

%module example
%{
#include "example.h"
%}
%include "example.h"

我可以使用 swig 生成包装器并将其测试为:

from example import Echo
import numpy as np

no = 2
Echo( np.int(no) )      # OK
Echo( np.int32(no) )    # Error
Echo( np.int64(no) )    # Error

swig 生成类型检查包装器代码,导致第二次和第三次调用出错。这很好,但是有什么方法可以 override/disable 为合法的类型转换生成这种类型检查代码吗?

您可以使用 SWIG 编写具有所需语义的类型映射。默认 int 类型映射对您不起作用的原因是它显式调用 PyLong_Check,这要求您的输入是 int 或其子类型。 numpy 类型不是这种情况,因此它会被拒绝,但是如果我们跳过该检查并直接跳转到 PyLong_AsLong 那么它将最终隐式调用 __int__ 方法以使转换成为可能。

因此将您的 SWIG 模块更改为:

%module example
%{
#include "example.h"
%}
%typemap(in) int %{
  // Skips PyLong_Check and calls PyLong_AsLong, which calls __int__ as needed
   = PyLong_AsLong($input);
  // But be aware of overflow semantics here. And note py3/py2 differences in PyLong/PyInt
  //
%}
%include "example.h"

足以使您的示例通过。

请注意,您也可以通过使用其重载解析机制在 SWIG 中实现相同的目的。

这可以通过在生成包装器时将 castmodenocastmode 选项传递给 swig 来控制。默认值为 nocastmode。这不需要定义任何 typemaps 并且也独立于 python2/python3.

示例: 要允许上述示例中的类型转换,可以生成包装器为:

swig -c++ -python -castmode example.i