禁止通过 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 中实现相同的目的。
这可以通过在生成包装器时将 castmode
或 nocastmode
选项传递给 swig 来控制。默认值为 nocastmode
。这不需要定义任何 typemaps
并且也独立于 python2/python3.
示例: 要允许上述示例中的类型转换,可以生成包装器为:
swig -c++ -python -castmode example.i
对于以下简单函数:
#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 中实现相同的目的。
这可以通过在生成包装器时将 castmode
或 nocastmode
选项传递给 swig 来控制。默认值为 nocastmode
。这不需要定义任何 typemaps
并且也独立于 python2/python3.
示例: 要允许上述示例中的类型转换,可以生成包装器为:
swig -c++ -python -castmode example.i