【问题标题】:Disable generation of implicit type checking code by swig for python-C++ interface通过 swig 为 python-C++ 接口禁用隐式类型检查代码的生成
【发布时间】:2017-10-02 10:33:13
【问题描述】:

对于以下简单函数:

#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 生成类型检查包装器代码,导致第二次和第三次调用出错。这很好,但是有什么方法可以覆盖/禁用为合法的类型转换生成这种类型检查代码?

【问题讨论】:

  • 您可以使用%renameEcho 重命名为EchoInternal,并使用%insert("python") 添加一个函数Echo,该函数将转换为int 并调用EchoInternal。没有旗帜可以引入某种放松

标签: python c++ swig


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

    您可以使用 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
      $1 = PyLong_AsLong($input);
      // But be aware of overflow semantics here. And note py3/py2 differences in PyLong/PyInt
      //
    %}
    %include "example.h"
    

    足以让您的示例通过。

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

    【讨论】:

      猜你喜欢
      • 2021-09-22
      • 2014-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-20
      • 1970-01-01
      相关资源
      最近更新 更多