加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

python – 用cython包装C类,让基本的例子工作

发布时间:2020-12-20 13:48:10 所属栏目:Python 来源:网络整理
导读:我正在尝试学习如何使用cython包装c代码.为了做到这一点,我从cython网页上的基本c示例开始,在这里找到: http://docs.cython.org/src/userguide/wrapping_CPlusPlus.html 这看起来很简单,但我无法让它工作.这是我做的: Rectangle.h和Rectangle.cpp直接从网
我正在尝试学习如何使用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;
}

然后我创建一个.pyx文件,名为“rect.pyx”,我在其中放入以下代码:

cdef extern from "Rectangle.h" namespace "shapes":
    cdef cppclass Rectangle:
        Rectangle(int,int,int) except +
        int x0,y1
        int getLength()
        int getHeight()
        int getArea()
        void move(int,int)

cdef class PyRectangle:
    cdef Rectangle *thisptr
    def __cinit__(self,int x0,int y1):
        self.thisptr = new Rectangle(x0,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并尝试导入该类时,我收到以下错误消息:

Traceback (most recent call last):
File "<stdin>",line 1,in <module>
ImportError: /home/codeFolder/rect.cpython-34m.so: undefined symbol: _ZN6shapes9Rectangle9getLengthEv

怎么了?

解决方法

查看您使用的链接中的setup.py和代码段:

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和or cythoniza文档中的更多细节;))

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读