当前位置:   article > 正文

c++ 代码 打包成python模块案例_将c++文件编译成python中的可调用模块

将c++文件编译成python中的可调用模块

本次使用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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 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; 
    }   
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 这里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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
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))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

编译

python setup.py build_ext --inplace
  • 1

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

代码获取链接

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/555721
推荐阅读
相关标签
  

闽ICP备14008679号