使用 SWIG 将 C++ 文件包装为 Python 文件

Wrapping a C++ file as a Python file using SWIG

我是 SWIG 的新手,作为一名程序员,我有点不知所措。我希望能够通过将包装的 class 作为模块 'import C++_file' 导入,然后在 python 2 中调用 C++ class 的函数,然后在我的 python class 类似 'C++_file.function(inputs)'.

http://intermediate-and-advanced-software-carpentry.readthedocs.io/en/latest/c++-wrapping.html 之后,我正在包装头文件 multiplyChannel.h:

#include <vector>
#include <complex>

using namespace std;

class MultiplyChannel {
    public:
        MultiplyChannel(double in_alpha);
        void applyToVector(vector<complex<double> > *in_signal);
    private:
        double alpha;
};

对应于我的示例 C++ 文件 multiplyChannel.cpp:

#include "multiplyChannel.h"
#include <vector>
#include <complex>

using namespace std;

MultiplyChannel::MultiplyChannel(double in_alpha){
    this->alpha = in_alpha;
}

void MultiplyChannel::applyToVector(vector<complex<double> > *in_signal){
    unsigned int size = in_signal->size();
    for (int i = 0; i < size; i++) {
        in_signal->at(i).real() = in_signal->at(i).real() * this->alpha;
        in_signal->at(i).imag() = in_signal->at(i).imag() * this->alpha;
    }
}

使用 makefile:

all:
    swig -python -c++ -o mult.cpp swigdemo.i
    python setup.py build_ext --inplace

包装文件swigdemo.i:

%module swigdemo

%{
#include <stdlib.h>
#include "multiplyChannel.h"
%}

%include "multiplyChannel.h"

和setup.py构建文件:

from distutils.core import setup, Extension

extension_mod = Extension("_swigdemo", ["mult.cpp"])

setup(name = "swigdemo", ext_modules=[extension_mod])

通过输入我的 Ubuntu 命令 window:

$ make
swig -python -c++ -o multiplyChannel.cpp swigdemo.i
python setup.py build_ext --inplace
running build_ext
$ python setup.py build
running build
running build_ext

使用 C++ 测试导入_tester.py,我尝试使用带有实例变量 'demo' 的 MultiplyChannel 对象 'demo' 将向量 [1, 2, 3] 乘以 [5, 10, 15] =45=] 的 5x,将所有输入乘以 5:

#!/usr/bin/python

import swigdemo

if __name__ == '__main__':
    demo = swigdemo.MultiplyChannel(in_alpha=5)
    out = demo.applyToVector(in_signal=[1, 2, 3])
    print(out)

我什至没有通过导入行,收到以下错误:

$ python C++_tester.py
ImportError: ./_swigdemo.so: undefined symbol: _ZN15MultiplyChannelC1Ed

而且我不确定该怎么做,因为我什至无法对 .so 文件进行 gedit 或 vim。我猜我的错误在于我的包装器、构建或生成文件中的包装不正确,因为 C++_tester.py 文件中的几乎所有内容都在我的 Pycharm IDE.[= 中自动完成20=]

非常感谢!

问题确实与扩展构建有关:

  • swigdemo.i - 生成 swig 包装器(mult.cpp )
  • MultiplyChannel class 实现在 multiplyChannel.cpp
  • 构建扩展时,因为它是一个 共享对象 (.so),链接器(默认情况下)不会抱怨关于未定义的符号(比如 2 MultiplyChannel 方法(因为它对它们一无所知) - 和其他),但是创建它,考虑到符号可以在 运行 时间可用(当.so 将被加载)

简而言之,通过将multiplyChannel.cpp添加到扩展源flies列表来修改setup.py

extension_mod = Extension("_swigdemo", ["mult.cpp", "multiplyChannel.cpp"])

检查 您将 运行 进入的下一个问题。