我正在尝试从cython调用C ++代码并遵循official guide。
但是,在python中导入已编译的模块时,我收到以下错误。
---------------------------------------------------------------------------
ImportError Traceback (most recent call last)
<ipython-input-1-ba16f97c2145> in <module>()
----> 1 import rect
ImportError: /home/userName/estCppLibrary/rect.so: undefined symbol: PyString_Type
我必须补充一点,我没有管理员权限,必须在~/.local/lib
本地安装Cython。在我的私人笔记本电脑上使用sudo权限和我的代码的默认路径。
这是我的代码。
#setup.py
from distutils.core import setup
from Cython.Build import cythonize
from distutils.extension import Extension
ext = Extension(
"rect",
sources = ["rect.pyx", "Rectangle.cpp"],
language = "c++",
include_dirs=["~/.local/include"],
library_dirs=["~/.local/lib"]
)
setup(ext_modules = cythonize(ext))
-
#Rectangle.h
namespace shapes {
class Rectangle {
public:
int x0, y0, x1, y1;
Rectangle();
Rectangle(int x0, int y0, int x1, int y1);
~Rectangle();
int getArea();
void getSize(int* width, int* height);
void move(int dx, int dy);
};
}
-
#Rectangle.cpp
namespace shapes {
Rectangle::Rectangle() { }
Rectangle::Rectangle(int X0, int Y0, int X1, int Y1) {
x0 = X0;
y0 = Y0;
x1 = X1;
y1 = Y1;
}
Rectangle::~Rectangle() { }
int Rectangle::getArea() {
return (x1 - x0) * (y1 - y0);
}
void Rectangle::getSize(int *width, int *height) {
(*width) = x1 - x0;
(*height) = y1 - y0;
}
void Rectangle::move(int dx, int dy) {
x0 += dx;
y0 += dy;
x1 += dx;
y1 += dy;
}
}
-
#rect.pyx
# distutils: language = c++
# distutils: sources = Rectangle.cpp
cdef extern from "Rectangle.h" namespace "shapes":
cdef cppclass Rectangle:
Rectangle() except +
Rectangle(int, int, int, int) except +
int x0, y0, x1, y1
int getArea()
void getSize(int* width, int* height)
void move(int, int)
cdef class PyRectangle:
cdef Rectangle c_rect # hold a C++ instance which we're wrapping
def __cinit__(self, int x0, int y0, int x1, int y1):
self.c_rect = Rectangle(x0, y0, x1, y1)
def get_area(self):
return self.c_rect.getArea()
def get_size(self):
cdef int width, height
self.c_rect.getSize(&width, &height)
return width, height
def move(self, dx, dy):
self.c_rect.move(dx, dy)