Python3.X использует Cython для вызова C/C++

Python C++

1 Создать код C++

Предположим, нам нужно позволить Python вызывать код C++ следующим образом (имя файлаdemo.h):

#ifndef DEMO_H
#define DEMO_H 
using namespace std;
namespace demo {
    class MyDemo {
        public:
            int a;
            MyDemo();
            MyDemo(int a );
            ~MyDemo(); 
            int mul(int m );
            int add(int b);
            void sayHello(char* name);
    };
}
#endif

Соответствующий код реализации C++ выглядит следующим образом (demo.cpp):

#include "demo.h" 
#include <iostream> 

namespace demo {
 
    MyDemo::MyDemo () {}
 
    MyDemo::MyDemo (int a) {
        this->a = a; 
    }
 
    MyDemo::~MyDemo () {}
 
    int MyDemo::mul(int m) {
        return this->a*m;
    }
 
    int MyDemo::add (int b) {
        return this->a+b;
    }
    void MyDemo::sayHello(char* name){
        cout<<"hello "<<name<<"!"<<endl;
    }

   
}

2 написатьpxdдокумент

pxdфайл можно увидеть какCython(которыйpyxфайл) заголовочные файлы, оpxdиpyxФайл можно понять просто следующим образом:

pxdфайлpyxиC/C++мост между.pyxдаC/C++иPythonмост между.

теперь, когдаpxdявляется заголовочным файлом, то есть сdemo.hочень похоже, создатьcdemo.pxdфайл, содержание следующее.

cdef extern from "demo.cpp":
    pass

# Decalre the class with cdef
cdef extern from "demo.h" namespace "demo":
    cdef cppclass MyDemo:
        MyDemo() except +
        MyDemo(int) except +
        int a
        int mul(int )
        int add(int )
        void sayHello(char*)

3 написатьpyxдокумент

Я сказал раньше,pyxфайлC/C++иPythonмост междуpyxфайл будетC/C++Код завернут в слой, что удобно для Python, чтобы напрямую вызывать и создаватьadapter.pyxфайл, код выглядит следующим образом.

# distutils: language = c++

from cdemo cimport MyDemo

# Create a Cython extension type which holds a C++ instance
# as an attribute and create a bunch of forwarding methods
# Python extension type.
cdef class PyMyDemo:
    cdef MyDemo c_mydemo  # Hold a C++ instance which we're wrapping

    def __cinit__(self,a):
        self.c_mydemo = MyDemo(a)   
    def mul(self, m):
        return self.c_mydemo.mul(m)

    def add(self,b):
        return self.c_mydemo.add(b)

    def sayHello(self,name ):
        self.c_mydemo.sayHello(name) 

Среди них первая линия# distutils: language = c++укажет текущий файл для созданияC++документ. Создайте класс PyMyDemo для использованияC/C++Код инкапсулирован в слой, поэтому Python можно вызывать напрямую.

4 Создатьsetup.pyдокумент

setup.pyФайл относительно простой, код выглядит следующим образом.

from distutils.core import setup

from Cython.Build import cythonize

setup(ext_modules=cythonize("adapter.pyx"))

5 Выполните компиляцию

Введите в консоли следующую команду:

python setup.py build_ext --inplace

После выполнения команды она будет сгенерирована в текущем каталогеadapter.cpp, этот документ основан наadapter.pyxСгенерировано. также будет генерироватьadapter.cp36-win_amd64.pydдокумент(LinuxВ соответствии с окружающей средойsoдокумент). здесьpydФайл является соответствующим файлом для платформы Windows, и это файл, который нам нужен.

6 тест

Результаты теста следующие

>>> from adapter import PyMyDemo
>>> demo=PyMyDemo(2)
>>> demo.add(1)
3
>>> demo.mul(2)
4
>>> demo.sayHello(b'HuaChao')
hello HuaChao!