Many Python libraries contain C/C++ code. When installing this library, you might encounter such an error:
error: unable to find vcvarsall.bat
There are two common solutions:
Generally, everyone will choose to install the compiled library files, or install mingw, but if you want to write extensions for your own Python programs under Windows, installing visual studio is the best solution.
The following introduces the common way of writing Python extension modules in C++.
First create an Exten.cpp file and write the following code:
# include "Python.h"//Function body
int add(int a,int b){return a + b;}//Wrapper function static PyObject*Exten_add(PyObject *self,PyObject *args){
int a,b;//Get data, i represents int, ii represents two ints//If it is not obtained, NULLif is returned(!PyArg_ParseTuple(args,"ii",&a,&b)){return NULL;}return(PyObject*)Py_BuildValue("i",add(a,b));}//Add PyMethodDef ModuleMethods[]Array static PyMethodDef ExtenMethods[]={//add: Function name that can be used for Python calls, Exten_add:C++Corresponding function name in{"add",Exten_add,METH_VARARGS},{NULL,NULL},};//Initialization function static struct PyModuleDef ExtenModule={
PyModuleDef_HEAD_INIT,"Exten",//Module name
NULL,-1,
ExtenMethods
}; voidPyInit_Exten(){PyModule_Create(&ExtenModule);}
Then create a setup.py file in the same folder and write the following code:
from distutils.core import setup,Extension
MOD ='Exten' #Module name
setup(name=MOD,ext_modules=[Extension(MOD,sources=['D:\\Exten.cpp'])])
Then enter in the CMD console:
python D:\\setup.py build
python D:\\setup.py install
This module has been installed successfully. It can be called directly in Python code:
>>> import Exten
>>> Exten.add(1,3)4
This method can only handle the task of incoming single data. If you need to process batch data such as batch arrays, you need to involve the conversion of Python objects to C++ objects.
Take the max function as an example. After adding the max function, you also need to write a wrapper function for max. The code in the entire Exten file is as follows:
# include "Python.h"
# include <vector>
# define INT_MIN -2147483648
using namespace std;//Function body
int add(int a,int b){return a + b;}
int max(vector<int> lst){
int max_num = INT_MIN;for(int i =0; i< lst.size(); i++){if(lst[i]> max_num){
max_num = lst[i];}}return max_num;}//Wrapper function static PyObject*Exten_add(PyObject *self,PyObject *args){
int a,b;//If no data is obtained if(!PyArg_ParseTuple(args,"ii",&a,&b)){return NULL;}return(PyObject*)Py_BuildValue("i",add(a,b));}//Every function in the module that can be called by Python needs a corresponding wrapper function static PyObject*Exten_max(PyObject *self,PyObject *args){
PyObject *obj;
vector<int> lst;//O stands for object if(!PyArg_ParseTuple(args,"O",&obj)){return NULL;}//Get iterable object
PyObject *iter =PyObject_GetIter(obj);if(!iter){PyErr_SetString(PyExc_TypeError,"The object is not iterable!");return NULL;}while(true){//Get each element in the list one by one
PyObject *next =PyIter_Next(iter);if(!next){break;}//Check if it is long or a subclass of long (including int) if(!PyLong_Check(next)){PyErr_SetString(PyExc_TypeError,"Int or Long list is expected!");return NULL;}//Converted from Python's Long to C/C++Long
long num =PyLong_AsLong(next);
lst.push_back(num);}return(PyObject*)Py_BuildValue("i",max(lst));}//Add PyMethodDef ModuleMethods[]Array static PyMethodDef ExtenMethods[]={//add: Function name that can be used for Python calls, Exten_add:C++Corresponding function name in{"add",Exten_add,METH_VARARGS},{"max",Exten_max,METH_VARARGS},{NULL,NULL},};//Initialization function static struct PyModuleDef ExtenModule={
PyModuleDef_HEAD_INIT,"Exten",//Module name
NULL,-1,
ExtenMethods
}; voidPyInit_Exten(){PyModule_Create(&ExtenModule);}
After taking the same way to build + install, you can use it:
>>> import Exten
>>> Exten.max([1,2,3,4])4>>> Exten.max([1,2,3,4.1])Traceback(most recent call last):
File "<stdin>", line 1,in<module>
TypeError: Int or Long list is expected!
Reference: https://blog.csdn.net/baidu_35085676/article/details/79518777
https://stackoverflow.com/questions/22458298/extending-python-with-c-pass-a-list-to-pyarg-parsetuple
https://docs.python.org/3/c-api/long.html
Recommended Posts