c++ 代码 打包成python模块案例

1 篇文章 0 订阅
0 篇文章 1 订阅

本次使用cython模块把一个已经用c++实现好了的库包装成python的一个模块。

案例目录结构

├── rectangle
│ ├── Rectangle.cpp
│ └── Rectangle.h
├── rect.pxd
├── rect.pyx
└── setup.py

  • rectangle目录是c++源码
  • 外层目录是python模块代码

c++原代码

  • Rectangle.h file
#ifndef RECTANGLE_H
#define RECTANGLE_H

namespace shape{
    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);
    };  
}
#endif
  • Rectangle.cpp file
#include<assert.h>
#include"Rectangle.h"

namespace shape{
    Rectangle::Rectangle(int x0,int y0,int x1,int y1):x0(x0),y0(y0),x1(x1),y1(y1){}
    
    Rectangle::Rectangle(){}

    int Rectangle::getArea()
    {   
        return (x0 - x1) * (y0 - y1);
    }   

    void Rectangle::getSize(int * width,int * height)
    {   
        assert(width != nullptr && height != nullptr);
        *width = x1 - x0; 
        *height = y1 - y0; 
    }   

    Rectangle::~Rectangle(){}

    void Rectangle::move(int dx,int dy) 
    {   
        x1 += dx; 
        x0 += dx; 
        y1 += dy; 
        y0 += dy; 
    }   
}

cython 包装

  • cython 包装需要写两个文件.pyx.pxd 文件,.pxd文件相当于头文件,声明你需要调用到的函数、变量、类等,因为cython不会去解析cpp的.h头文件,所以需要用.pxd文件声明一下。
rect.pxd代码
cdef extern from "Rectangle.h" namespace "shape":
    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)
  • 这里except +作用是把c++ 代码中异常传递出来
  • 这些声明基本和c++头文件差不多
rect.pyx代码
cimport rect   # 导入上面写的rect.pxd 文件

cdef class Rectangle:    #定义一个python类

   cdef rect.Rectangle _rect   #因为pxd文件声明过,这里可以使用Rectagnle这c++类

   def __cinit__(self,x0,y0,x1,y1):
      self._rect = rect.Rectangle(x0,y0,x1,y1)

   def get_area(self):
       return self._rect.getArea()

   def get_size(self):
       cdef int width,height;
       self._rect.getSize(&width,&height)
       return width,height

   def move(self,dx,dy):
       self._rect.move(dx,dy)

   #属性访问
   @property
   def x0(self):
   @x0.setter
   def x0(self,x0):
       self._rect.x0 = x0

   @property
   def x1(self):
       return self._rect.x1
   @x1.setter
   def x1(self, x1):
       self._rect.x1 = x1

   @property
   def y0(self):
       return self._rect.y0
   @y0.setter
   def y0(self, y0):
       self._rect.y0 = y0

   @property
   def y1(self):
       return self._rect.y1
   @y1.setter
   def y1(self, y1):
       self._rect.y1 = y1
setup.py代码
from distutils.core import setup,Extension
from Cython.Build import cythonize

ext = Extension("Rectangle",
        sources=["rect.pyx","rectangle/Rectangle.cpp"],
        include_dirs=["rectangle"],   # c++的头文件目录
        language="c++"
        )
setup(ext_modules=cythonize(ext))

编译

python setup.py build_ext --inplace

编译成功后会直接在当前目录下生成一个库文件
或者使用 python setup.py build 进行编译
python setup.py install进行安装,然后全局就可以使用这个模块了。

代码获取链接

https://download.csdn.net/download/weixin_42081309/11834279

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值