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!