Python3调用C++:一些简单的参数和返回的例子

Posted 肥宝Fable

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python3调用C++:一些简单的参数和返回的例子相关的知识,希望对你有一定的参考价值。

#include <Python.h> 
#include <iostream>
#include <vector>
using namespace std;

typedef vector<double> SeqDouble;
typedef vector<SeqDouble> SeqSeqDouble;

//普通参数的输入
void test1(int a, char* b, double c)

	std::cout << a << "," << b << "," << c << std::endl;


//普通参数的输出
int add(int a, int b)

	std::cout << a << "+"<< b << std::endl;
	return 10086;


//一维数组
//将c++中的vector<double>转换为python的list
PyObject* c2p_oneDData(SeqDouble& ds)

	int labelSize = ds.size();
	printf("c++ data size:%d\\n", labelSize);
	PyObject* py_data = PyList_New(labelSize);

	for (int i = 0; i < labelSize; ++i) 
		PyList_SetItem(py_data, i, Py_BuildValue("d", ds[i]));
	
	return py_data;


//一维数组的输入与输出例子
static PyObject* pyTest2(PyObject* self, PyObject* args)

	//一维数组的输入
	PyObject* py_data; // python中传入的输入参数
	if (!PyArg_ParseTuple(args, "O", &py_data)) // 获取到python文件中的输入参数(python 2 c++)
	
		return NULL;
	 
	SeqDouble ds;
	int retSize = PyList_Size(py_data);
 	for (int i = 0; i < retSize; ++i)
 	
 		PyObject* pItem = PyList_GetItem(py_data, i);
 		double d = PyFloat_AsDouble(pItem);
		cout << "d:" << d << endl;
 		ds.push_back(d + 1.234);
 	

	//一维数组的输出  
	PyObject* py_data2 = PyList_New(retSize);

	for (int i = 0; i < retSize; ++i) 
	
		PyList_SetItem(py_data2, i, Py_BuildValue("d", ds[i]));
	
	return py_data2;




//2维数组的输入与输出例子
static PyObject* pyTest3(PyObject* self, PyObject* args)

	//2维数组的输入
	PyObject* py_data; // python中传入的输入参数
	if (!PyArg_ParseTuple(args, "O", &py_data)) // 获取到python文件中的输入参数(python 2 c++)
	
		return NULL;
	
	SeqSeqDouble dss;
	int retSize = PyList_Size(py_data); 
	for (int i = 0; i < retSize; ++i)
	 
		PyObject* pItem = PyList_GetItem(py_data, i);
		int retSize2 = PyList_Size(pItem);
		SeqDouble ds;
		for (int j = 0; j < retSize2; ++j)
		
			PyObject* pItem2 = PyList_GetItem(pItem, j);
			double d = PyFloat_AsDouble(pItem2);
			cout << d << ",";
			ds.push_back(d + 1.234);
		
		cout << endl;
		dss.push_back(ds);
	

	//2维数组的输出  
	PyObject* py_data2 = PyList_New(retSize); 
	for (int i = 0; i < retSize; ++i)
	
		int size2 = dss[i].size();
		PyObject* py_data3 = PyList_New(size2);
		for (int j = 0; j < size2; ++j )
		
			PyList_SetItem(py_data3, j, Py_BuildValue("d", dss[i][j]));
		
		PyList_SetItem(py_data2, i, Py_BuildValue("O", py_data3));
	
	return py_data2;




//如果C函数没有返回值(返回 void 的函数),则必须返回None(可以用Py_RETUN_NONE宏来完成):
static PyObject* WrappAdd(PyObject* self, PyObject* args)

	int a = 0;
	int b = 0;
	//解析参数
	if (!PyArg_ParseTuple(args, "ii", &a, &b))
	
		return NULL;
	
	//调用函数,并返回结果
	int c = add(a, b);
	//返回结果给Python
	return Py_BuildValue("i", c);


static PyObject* pyTest(PyObject* self, PyObject* args)

	int a = 0;
	char* b = "";
	double c = 0;
	//解析参数
	if (!PyArg_ParseTuple(args, "isd", &a, &b, &c))
	
		return NULL;
	
	//调用函数,并返回结果
	test1(a, b, c);
	//返回结果给Python
	Py_INCREF(Py_None);
	return Py_None;


//把函数封装成模块
//为使得函数能够被python调用,需要先定义一个方发表“method table”。
//第三个参数(METH_VARARGS),这个标志指定会使用C的调用惯例。
//可选值有METH_VARARGS、METH_VARARGS|METH_KEYWORDS。值0代表使用PyArg_ParseTuple()的过时的变量。
//如果单独使用METH_VARARGS,函数会等待Python传来tuple格式的参数,并最终使用PyArg_ParseTuple()进行解析。
//METH_KEYWORDS值表示接受关键字参数。这种情况下C函数需要接受第三个PyObject*对象,表示字典参数,
//使用 PyArg_ParseTupleAndKeywords()来解析出参数。
static PyMethodDef methods[] = 

	//python中的函数名,C++中的函数名,XXX,XXX
	 "Add", WrappAdd, METH_VARARGS, "something" ,
	 "test", pyTest, METH_VARARGS, "something" ,
	 "test2", pyTest2, METH_VARARGS, "something" ,
	 "test3", pyTest3, METH_VARARGS, "something" ,
	 NULL, NULL , 0, NULL 
;

//上一个方法表必须被模块定义结构所引用。
//这个结构体必须传递给解释器的模块初始化函数。
static struct PyModuleDef PCmodule = 

	PyModuleDef_HEAD_INIT,
	"PyCallCpp",   /* name of module */
	NULL, /* module documentation, may be NULL */
	-1,       /* size of per-interpreter state of the module, or -1 if the module keeps state in global variables. */
	methods
;

//始化函数必须命名为PyInit_name(),其中name是module的名字,并应该定义为非static,且在模块文件里。
PyMODINIT_FUNC PyInit_PyCallCpp(void)

	return PyModule_Create(&PCmodule);

 

以上是关于Python3调用C++:一些简单的参数和返回的例子的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Spring/Hibernate 调用存储的例程/函数?

C++ 调用Python3

C++程序调用python3

在 C++ 程序中调用 Cython (Python3.6)

C++返回值为对象时复制构造函数不执行怎么破

Python3基础 定义无参数无返回值函数 调用会输出hello world的函数