我现在在macbook上尝试了相同的代码,它运行正常。因此,问题仅限于我的Linux Mint 17.2系统,包括anaconda python 2.7,cython 0.23.4和gcc 4.8。 Macbook使用的是anaconda python 2.7,cython 0.22.1和Apple LLVM 6.1.0版。
我正在尝试从这里开始使用Cython c ++示例:http://docs.cython.org/src/userguide/wrapping_CPlusPlus.html
由于有一些解释空间,我的确切代码粘贴在下面。它全部在一个目录cpp_example
中。在cpp_example
目录中,我使用:
>python setup.py build_ext --inplace
编译打印以下输出:
Compiling rect.pyx because it changed.
[1/1] Cythonizing rect.pyx
running build_ext
building 'rect' extension
gcc -pthread -fno-strict-aliasing -g -O2 -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC -I/home/jason/anaconda/envs/martian/include/python2.7 -c rect.cpp -o build/temp.linux-x86_64-2.7/rect.o
cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid for C/ObjC but not for C++ [enabled by default]
gcc -pthread -fno-strict-aliasing -g -O2 -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC -I/home/jason/anaconda/envs/martian/include/python2.7 -c Rectangle.cpp -o build/temp.linux-x86_64-2.7/Rectangle.o
cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid for C/ObjC but not for C++ [enabled by default]
g++ -pthread -shared -L/home/jason/anaconda/envs/martian/lib -Wl,-rpath=/home/jason/anaconda/envs/martian/lib,--no-as-needed build/temp.linux-x86_64-2.7/rect.o build/temp.linux-x86_64-2.7/Rectangle.o -L/home/jason/anaconda/envs/martian/lib -lpython2.7 -o build/lib.linux-x86_64-2.7/rect.so
然后我尝试跑:
>python main.py
我收到了这个错误:
Traceback (most recent call last):
File "main.py", line 1, in <module>
import rect
ImportError: /home/jason/projects/martian/workspaces/workspace1/cpp_example/rect.so: undefined symbol: _ZN6shapes9Rectangle9getLengthEv
未定义的符号看起来像是Rectangle c ++类的getLength方法的错误版本。我不确定我做错了什么,或者我的系统设置方式是否有问题。任何可能出现问题的建议都将不胜感激。
Rectangle.cpp:
#include "Rectangle.h"
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;
}
}
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);
};
}
rect.pyx:
# distutils: sources = Rectangle.cpp
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 # hold a C++ instance which we're wrapping
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
language="c++", # generate C++ code
))
main.py:
import rect
print rect.PyRectangle(1,1,2,2)