将 C++ 包装到 python 的 Swig 使用默认值 Python 而不是 Mac OS X 中的 Anaconda python
Swig wrapping C++ to python is using default Python rather than Anaconda python in Mac OS X
我正在尝试使用 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 中的设置文件来构建库的解释。这创造了奇迹:)
我遇到的下一个问题是包装简单 class:
我的 class 来自 [示例] 的代码 (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
文件是否正确?我只是想按照示例进行简单包装,显然网上没有简单的教程。
我也可以在其他不同的问题上问这个问题,但我想现在就在这里继续。
Warren Weckesser 在类似 问题中的回答
。我按照答案中的建议使用了 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
我正在尝试使用 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
如果我尝试通过通过 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 中的设置文件来构建库的解释。这创造了奇迹:)
我遇到的下一个问题是包装简单 class:
我的 class 来自 [示例] 的代码 (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
文件是否正确?我只是想按照示例进行简单包装,显然网上没有简单的教程。
我也可以在其他不同的问题上问这个问题,但我想现在就在这里继续。
Warren Weckesser 在类似 问题中的回答
。我按照答案中的建议使用了 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