无法使用 SWIG 在 Python 中实例化 C++ 类(获取属性错误)

Posted

技术标签:

【中文标题】无法使用 SWIG 在 Python 中实例化 C++ 类(获取属性错误)【英文标题】:Cannot instantiate a C++ class in Python using SWIG (Gets Attribute error) 【发布时间】:2018-10-22 13:39:56 【问题描述】:

我想将 C++ 类导出到 Python,为此我使用 SWIG 创建了一个 C++ 扩展模块。从文档中,我可以看到可以使用 SWIG 导出类。我能够成功地为 python 创建类模块(_minimal.pyd)。我可以在 Python 中导入模块。但是,我无法创建该类的对象,并且出现 Attribute 错误。请找到我尝试过的代码示例。谁能帮帮我?

//minimal.h
class minimal

private:
    static int num_instances;

public:
    minimal()
    
        ++num_instances;
    
    ~minimal()
    
        --num_instances;
    

    void print_num_instances();
;

//minimal.cpp
#include <iostream>
#include "minimal.h"

int minimal::num_instances = 0;

void minimal::print_num_instances()

    using namespace std;
    cout << this->num_instances << endl;


//minimal.i(interface file)
%module minimal

%
#include "minimal.h"
%

%include "minimal.h"

//python code used to run the module
import _minimal as m
m1=m.minimal()

【问题讨论】:

【参考方案1】:

SWIG 生成 minimal_wrap.cxxminimal.py。当您将 .cxx 文件构建为 _minimal.pyd 时,您将使用 import minimal,而不是 import _minimal

>>> import minimal
>>> x=minimal.minimal()
>>> x.print_num_instances()
1
>>> y=minimal.minimal()
>>> x.print_num_instances()
2

有关参考,请参阅 SWIG Python 文档中的36.2.1 Running SWIG。引用:

...[Running swig -c++ -python] 这会创建两个不同的文件;一个 C/C++ 源文件 example_wrap.c 或 example_wrap.cxx 和一个 Python 源文件 example.py。生成的 C 源文件包含需要编译并与 C/C++ 应用程序的其余部分链接以创建扩展模块的低级包装器。 Python 源文件包含高级支持代码。这是您将导入以使用该模块的文件。

【讨论】:

非常感谢您的回复。但我无法将其导入为最小导入。它会抛出错误模块未找到。我正在使用 Visual Studio 2015 和 Python 3.6.5 Anaconda 发行版。 @AparnaBose 我猜你在接受答案后找到了它? :^) 先生..你能告诉我使用的编译器和python版本吗?这可能是什么问题吗?我可以使用 import _modulename 导入和使用斐波那契函数。但不是课程。 不,先生...您的回答是有效的,因为我想知道为什么我们必须在编译器设置中使用下划线。 _modulename.pyd 文件并不意味着直接导入。 SWIG 还会生成 modulename.py,而 modulename.py 又会导入 _modulename.pyd。很可能您构建了 _modulename.pyd,但没有将 modulename.py 文件移动到与 .pyd 相同的目录中。

以上是关于无法使用 SWIG 在 Python 中实例化 C++ 类(获取属性错误)的主要内容,如果未能解决你的问题,请参考以下文章

SWIG C++ Python 多态性和多线程

如何用 swig 实例化模板类的模板方法?

无法从使用 SWIG 创建的 python 访问 C++ 扩展模块及其方法

SWIG C++ 到 Python:在抛出 ... 的实例后调用终止

无法为 c++ python 扩展编译 swig 生成的包装器

c 的 SWIG python 绑定找不到标准头文件的 _EXFUN