【问题标题】:Swig wrapping C++ to python is using default Python rather than Anaconda python in Mac OS XSwig 将 C++ 包装到 python 是在 Mac OS X 中使用默认 Python 而不是 Anaconda python
【发布时间】:2015-11-23 09:56:11
【问题描述】:

我正在尝试使用 swig 将 c++ 函数包装到 python 中。我正在使用以下命令

swig -c++ -python helloworld.i
g++ -O2 -fPIC -c hello.cpp
g++ -O2 -fPIC -c helloworld_wrap.cxx -I//anaconda/include/python2.7
g++ -lpython -dynamclib hello.o helloworld_wrap.o -o _helloworld.so

hello.cpp 是带有函数的初始文件,helloworld.i 是带有包装器的文件。这些命令创建库helloworld但我只能通过/usr/bin/python中的默认python导入它

如果我尝试通过 anaconda 安装的python 导入它,则会出现以下错误:

Fatal Python error: PyThreadState_Get: no current thread
Abort trap: 6  

你能告诉我如何用 anaconda 的python 包装代码吗?

找到了解决办法:Python.h not found using swig and Anaconda Python

在上面的问题中,最上面的答案给出了使用disutils和python中的设置文件来构建库的解释。这创造了奇迹:)

我在包装简单类时遇到的下一个问题:

我的课程代码来自 [example] (http://web.mit.edu/svn/src/swig-1.3.25/Examples/python/class/index.html)

/* File : example.h */

class Shape {
public:
  Shape() {
    nshapes++;
  }
  virtual ~Shape() {
    nshapes--;
  };
  double  x, y;   
  void    move(double dx, double dy);
  virtual double area() = 0;
  virtual double perimeter() = 0;
  static  int nshapes;
};

class Circle : public Shape {
    private:
  double radius;
public:
  Circle(double r) : radius(r) { };
  virtual double area();
  virtual double perimeter();
};

class Square : public Shape {
private:
  double width;
public:
  Square(double w) : width(w) { };
  virtual double area();
  virtual double perimeter();
};  

我的setup.py 文件:

#setup.py file:

from setuptools import setup, Extension

setup(name='example',

    version='0.1',

    ext_modules=[Extension('_example', ['example.h', 'example.i'],
                swig_opts=['-c++'],
                )],

    )  

我用来包装的代码:

python setup.py build_ext --inplace  

错误信息:

running build_ext
building '_example' extension
swigging example.i to example_wrap.cpp
swig -python -c++ -o example_wrap.cpp example.i
error: unknown file type '.h' (from 'example.h')  

你能建议这里有什么问题吗?我想它没有识别“.h”文件,但由于它是头文件,我认为它可以保持原样。另外,如果我的setup.py 文件正确与否?我只是想按照简单包装的例子,显然没有简单的在线教程。
我也可以就其他不同的问题提出这个问题,但我想暂时继续在这里。

【问题讨论】:

  • 是的,您引用的答案完美地回答了您的问题(使用 distutils 甚至不使用)。那么,如果您已经知道答案,那么发布您的问题究竟有什么意义呢?
  • @m7thon 实际上,我首先发布了这个问题,后来才找到解决方案。所以我也在这里添加了解决方案。我应该把这个问题记下来吗?或者我怎么说它是关闭的?
  • 我明白了。我想最好的办法是将您找到的解决方案作为答案发布。那么很明显这个问题确实得到了回答。
  • 好的,谢谢 :) 我还想问你一些关于 C++ 类包装的问题,因为你似乎在这个领域非常了解。我的类有很多继承要包装,但我现在正在尝试主要使用这个example 处理基本类我已经添加了我在上面使用的setup.py 文件以及我得到的错误,你建议我发生了什么。正如我之前告诉过你的那样,我对此很陌生,对该领域的知识不多。任何帮助将不胜感激。 :)
  • 要问一个新问题,你应该开始一个新问题。很快,正如您所猜测的,您不应该编译头文件。 setup.py 中列出的扩展源文件应该是 example.cpp 和 example.i。

标签: python macos swig


【解决方案1】:

Warren Weckesser 在类似的question 中回答。我按照答案中的建议使用了setup.py 文件,并将库的路径添加到sys.path 并且效果很好:)

gcc 命令中使用选项-I/Users/myuser/anaconda/include/python2.7。 (假设您使用的是 python 2.7。更改名称以匹配您正在使用的 python 版本。)您可以使用命令python-config --cflags 获取完整的推荐编译标志集:

$ python-config --cflags
-I/Users/myuser/anaconda/include/python2.7 -I/Users/myuser/anaconda/include/python2.7 -fno-strict-aliasing -I/Users/myuser/anaconda/include -arch x86_64 -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes

但是,要构建扩展模块,我建议使用简单的设置脚本,例如以下setup.py,并让distutils 为您找出所有编译和链接选项。

# setup.py

from distutils.core import setup, Extension


example_module = Extension('_example', sources=['example_wrap.c', 'example.c'])

setup(name='example', ext_modules=[example_module], py_modules=["example"])

然后就可以运行了:

$ swig -python example.i
$ python setup.py build_ext --inplace

(查看运行setup.py 时回显到终端的编译器命令。)

distutils 了解 SWIG,因此您可以将example.i 包括在源文件列表中,而不是在源文件列表中包括example_wrap.c,并且swig 将由安装脚本自动运行:

# setup.py

from distutils.core import setup, Extension


example_module = Extension('_example', sources=['example.c', 'example.i'])

setup(name='example', ext_modules=[example_module], py_modules=["example"])

使用上面版本的setup.py,你可以用单个命令构建扩展模块

$ python setup.py build_ext --inplace

一旦你构建了扩展模块,你应该就可以在 python 中使用它了:

>>> import example
>>> example.fact(5)
120

如果您不想使用脚本 setup.py,这里有一组对我有用的命令:

$ swig -python example.i
$ gcc -c -I/Users/myuser/anaconda/include/python2.7 example.c example_wrap.c 
$ gcc -bundle -undefined dynamic_lookup -L/Users/myuser/anaconda/lib example.o example_wrap.o -o _example.so

注意:我使用的是 Mac OS X 10.9.4:

$ gcc --version
Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)
Target: x86_64-apple-darwin13.3.0
Thread model: posix

【讨论】:

    猜你喜欢
    • 2017-12-18
    • 2022-11-29
    • 1970-01-01
    • 2015-05-23
    • 2021-05-23
    • 2014-08-31
    • 1970-01-01
    • 2014-05-11
    • 2017-06-27
    相关资源
    最近更新 更多