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 调用存储的例程/函数?