Pythonの多くのライブラリにはC / C ++コードが含まれています。このライブラリをインストールすると、次のエラーが発生する場合があります。
error: unable to find vcvarsall.bat
2つの一般的な解決策があります。
通常、誰もがコンパイルされたライブラリファイルをインストールするかmingwをインストールするかを選択しますが、Windowsで独自のPythonプログラムの拡張機能を作成する場合は、visualstudioをインストールするのが最善の解決策です。
以下では、C ++でPython拡張モジュールを作成する一般的な方法を紹介します。
最初にExten.cppファイルを作成し、次のコードを記述します。
# include "Python.h"//機能本体
int add(int a,int b){return a + b;}//ラッパー関数staticPyObject*Exten_add(PyObject *self,PyObject *args){
int a,b;//データを取得します。iはintを表し、iiは2つのintを表します。//取得されない場合、NULLifが返されます(!PyArg_ParseTuple(args,"ii",&a,&b)){return NULL;}return(PyObject*)Py_BuildValue("i",add(a,b));}//PyMethodDefModuleMethodsを追加します[]配列静的PyMethodDefExtenMethods[]={//追加:Python呼び出しに使用できる関数名、Exten_add:C++の対応する関数名{"add",Exten_add,METH_VARARGS},{NULL,NULL},};//初期化関数staticstruct PyModuleDef ExtenModule={
PyModuleDef_HEAD_INIT,"Exten",//モジュール名
NULL,-1,
ExtenMethods
}; voidPyInit_Exten(){PyModule_Create(&ExtenModule);}
次に、同じフォルダーにsetup.pyファイルを作成し、次のコードを記述します。
from distutils.core import setup,Extension
MOD ='Exten' #モジュール名
setup(name=MOD,ext_modules=[Extension(MOD,sources=['D:\\Exten.cpp'])])
次に、CMDコンソールに次のように入力します。
python D:\\setup.py build
python D:\\setup.py install
このモジュールは正常にインストールされました。 Pythonコードで直接呼び出すことができます。
>>> import Exten
>>> Exten.add(1,3)4
このメソッドは、単一のデータ受信タスクのみを処理できます。バッチ配列などのバッチデータを処理する必要がある場合は、PythonオブジェクトからC ++オブジェクトへの変換を行う必要があります。
max関数を例にとると、max関数を追加した後、maxのラッパー関数も作成する必要があります。Extenファイル全体のコードは次のとおりです。
# include "Python.h"
# include <vector>
# define INT_MIN -2147483648
using namespace std;//機能本体
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;}//ラッパー関数staticPyObject*Exten_add(PyObject *self,PyObject *args){
int a,b;//データが取得されない場合(!PyArg_ParseTuple(args,"ii",&a,&b)){return NULL;}return(PyObject*)Py_BuildValue("i",add(a,b));}//Pythonで呼び出すことができるモジュール内のすべての関数には、対応するラッパー関数staticPyObjectが必要です。*Exten_max(PyObject *self,PyObject *args){
PyObject *obj;
vector<int> lst;//Oはオブジェクトを表します(!PyArg_ParseTuple(args,"O",&obj)){return NULL;}//反復可能なオブジェクトを取得する
PyObject *iter =PyObject_GetIter(obj);if(!iter){PyErr_SetString(PyExc_TypeError,"The object is not iterable!");return NULL;}while(true){//リスト内の各要素を1つずつ取得します
PyObject *next =PyIter_Next(iter);if(!next){break;}//それがlongであるか、longのサブクラス(intを含む)であるかどうかを確認します。(!PyLong_Check(next)){PyErr_SetString(PyExc_TypeError,"Int or Long list is expected!");return NULL;}//PythonのLongからCに変換/C++長いです
long num =PyLong_AsLong(next);
lst.push_back(num);}return(PyObject*)Py_BuildValue("i",max(lst));}//PyMethodDefModuleMethodsを追加します[]配列静的PyMethodDefExtenMethods[]={//追加:Python呼び出しに使用できる関数名、Exten_add:C++の対応する関数名{"add",Exten_add,METH_VARARGS},{"max",Exten_max,METH_VARARGS},{NULL,NULL},};//初期化関数staticstruct PyModuleDef ExtenModule={
PyModuleDef_HEAD_INIT,"Exten",//モジュール名
NULL,-1,
ExtenMethods
}; voidPyInit_Exten(){PyModule_Create(&ExtenModule);}
同じ方法でビルド+インストールした後、次のように使用できます。
>>> 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!
参照:[https://blog.csdn.net/baidu_35085676/article/details/79518777](https://link.zhihu.com/?target=https%3A//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