用 cython 包装 C++ Class,让基本示例工作
Wrap C++ Class with cython, getting the basic example to work
我正在尝试了解如何使用 cython 包装 C++ 代码。为了做到这一点,我从 cython 网页上的基本 C++ 示例开始,可以在此处找到:http://docs.cython.org/src/userguide/wrapping_CPlusPlus.html
这看起来很简单,但我无法让它工作。这是我所做的:
Rectangle.h和Rectangle.cpp直接从网页复制
Rectangle.h:
namespace shapes {
class Rectangle {
public:
int x0, y0, x1, y1;
Rectangle(int x0, int y0, int x1, int y1);
~Rectangle();
int getLength();
int getHeight();
int getArea();
void move(int dx, int dy);
};
}
Rectangle.cpp
#include "Rectangle.h"
using namespace shapes;
Rectangle::Rectangle(int X0, int Y0, int X1, int Y1) {
x0 = X0;
y0 = Y0;
x1 = X1;
y1 = Y1;
}
Rectangle::~Rectangle() {
}
int Rectangle::getLength() {
return (x1 - x0);
}
int Rectangle::getHeight()
{
return (y1 - y0);
}
int Rectangle::getArea() {
return (x1 - x0) * (y1 - y0);
}
void Rectangle::move(int dx, int dy) {
x0 += dx;
y0 += dy;
x1 += dx;
y1 += dy;
}
然后我创建一个名为 "rect.pyx" 的 .pyx 文件,我在其中放置了以下代码:
cdef extern from "Rectangle.h" namespace "shapes":
cdef cppclass Rectangle:
Rectangle(int, int, int, int) except +
int x0, y0, x1, y1
int getLength()
int getHeight()
int getArea()
void move(int, int)
cdef class PyRectangle:
cdef Rectangle *thisptr
def __cinit__(self, int x0, int y0, int x1, int y1):
self.thisptr = new Rectangle(x0, y0, x1, y1)
def __dealloc__(self):
del self.thisptr
def getLength(self):
return self.thisptr.getLength()
def getHeight(self):
return self.thisptr.getHeight()
def getArea(self):
return self.thisptr.getArea()
def move(self, dx, dy):
self.thisptr.move(dx, dy)
最后,一个 "setup.py" 文件:
from distutils.core import setup
from Cython.Build import cythonize
setup(ext_modules = cythonize(
"rect.pyx", # our Cython source
sources=["Rectangle.cpp"], # additional source file(s)
language="c++", # generate C++ code
))
我尝试在 ubuntu 和 mac osx 上通过 运行 终端中的以下命令构建代码(我在两个操作上得到相同的结果系统):
python3 setup.py build_ext --inplace
这似乎编译正常,文件夹中出现了一个新的 .cpp 文件和一个 .so 文件,但是当我启动 python 并尝试导入 class 时,我得到了以下错误消息:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: /home/codeFolder/rect.cpython-34m.so: undefined symbol: _ZN6shapes9Rectangle9getLengthEv
怎么了?
查看您的 setup.py 和您使用的 link 中的代码段:
from distutils.core import setup, Extension
from Cython.Build import cythonize
setup(ext_modules = cythonize(Extension(
"rect", # the extesion name
sources=["rect.pyx", "Rectangle.cpp"], # the Cython source and
# additional C++ source files
language="c++", # generate and compile C++ code
)))
基本上,您错过了对 Extension 的调用(在 Extension 和/或 cythoniza 文档中有更多详细信息;))
我正在尝试了解如何使用 cython 包装 C++ 代码。为了做到这一点,我从 cython 网页上的基本 C++ 示例开始,可以在此处找到:http://docs.cython.org/src/userguide/wrapping_CPlusPlus.html
这看起来很简单,但我无法让它工作。这是我所做的:
Rectangle.h和Rectangle.cpp直接从网页复制
Rectangle.h:
namespace shapes {
class Rectangle {
public:
int x0, y0, x1, y1;
Rectangle(int x0, int y0, int x1, int y1);
~Rectangle();
int getLength();
int getHeight();
int getArea();
void move(int dx, int dy);
};
}
Rectangle.cpp
#include "Rectangle.h"
using namespace shapes;
Rectangle::Rectangle(int X0, int Y0, int X1, int Y1) {
x0 = X0;
y0 = Y0;
x1 = X1;
y1 = Y1;
}
Rectangle::~Rectangle() {
}
int Rectangle::getLength() {
return (x1 - x0);
}
int Rectangle::getHeight()
{
return (y1 - y0);
}
int Rectangle::getArea() {
return (x1 - x0) * (y1 - y0);
}
void Rectangle::move(int dx, int dy) {
x0 += dx;
y0 += dy;
x1 += dx;
y1 += dy;
}
然后我创建一个名为 "rect.pyx" 的 .pyx 文件,我在其中放置了以下代码:
cdef extern from "Rectangle.h" namespace "shapes":
cdef cppclass Rectangle:
Rectangle(int, int, int, int) except +
int x0, y0, x1, y1
int getLength()
int getHeight()
int getArea()
void move(int, int)
cdef class PyRectangle:
cdef Rectangle *thisptr
def __cinit__(self, int x0, int y0, int x1, int y1):
self.thisptr = new Rectangle(x0, y0, x1, y1)
def __dealloc__(self):
del self.thisptr
def getLength(self):
return self.thisptr.getLength()
def getHeight(self):
return self.thisptr.getHeight()
def getArea(self):
return self.thisptr.getArea()
def move(self, dx, dy):
self.thisptr.move(dx, dy)
最后,一个 "setup.py" 文件:
from distutils.core import setup
from Cython.Build import cythonize
setup(ext_modules = cythonize(
"rect.pyx", # our Cython source
sources=["Rectangle.cpp"], # additional source file(s)
language="c++", # generate C++ code
))
我尝试在 ubuntu 和 mac osx 上通过 运行 终端中的以下命令构建代码(我在两个操作上得到相同的结果系统):
python3 setup.py build_ext --inplace
这似乎编译正常,文件夹中出现了一个新的 .cpp 文件和一个 .so 文件,但是当我启动 python 并尝试导入 class 时,我得到了以下错误消息:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: /home/codeFolder/rect.cpython-34m.so: undefined symbol: _ZN6shapes9Rectangle9getLengthEv
怎么了?
查看您的 setup.py 和您使用的 link 中的代码段:
from distutils.core import setup, Extension
from Cython.Build import cythonize
setup(ext_modules = cythonize(Extension(
"rect", # the extesion name
sources=["rect.pyx", "Rectangle.cpp"], # the Cython source and
# additional C++ source files
language="c++", # generate and compile C++ code
)))
基本上,您错过了对 Extension 的调用(在 Extension 和/或 cythoniza 文档中有更多详细信息;))