C++调用Python
Python版本3.6
C++和Python类型对应表
C++ | Python | FormatCode |
---|---|---|
char* | str | s |
char*/Null | str/None | z |
int | int | i |
long | long | l |
char | str | c |
double | float | d |
Py_Complex* | complex | D |
PyObject* | (any) | O |
PyStringObject* | str | S |
需要Python的依赖
- 需要包含的头文件
#include <Python.h> - 需要的库
Debug : python36.lib
Release: python36_d.lib
C++初始调用Python的方法
初始化
Py_Initialize();
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./Python')"); // Python是.py或.pyd所在的目录
引入模块
PyObject *pModule = PyImport_ImportModule(“test”); // 接口文件,如test.py
获取模块字典属性
- 获取模块中的函数或类的成员函数
PyObject *pDict = PyModule_GetDict(pModule); // 所有的类和函数都是从pDict中获取的
通过字典属性获取模块中的类
PyObject *pClass = PyDict_GetItemString(pDict, “ShowInfo”); // ShowInfo是一个类
-
如果ShowInfo构造函数有参数,以含有两个参数为例,如下:
PyObject* cons_args = PyTuple_New(2);
PyTuple_SetItem(cons_args, 0, Py_BuildValue(“s”, “hello”));
PyTuple_SetItem(cons_args, 1, Py_BuildValue(“i”, 1)); -
构造一个实例出来
PyObject *pInstance = PyObject_CallObject(pClass, cons_args); -
调用成员函数,(i),传入参数的类型
有参函数的调用:
PyObject* resultPoints = PyObject_CallMethod(pInstance, “GetPoint”, “(i)”, 100);
无参函数的调用:
PyObject* result = PyObject_CallMethod(pInstance, “ShowDetail”, “”, “”);
资源释放
Py_Finalize();
完整代码示例:
C++代码
#include <iostream>
#include <stdlib.h>
#include <iostream>
#include <vector>
#include <Python.h>
using namespace std;
typedef struct vec31
{
vec31(float a, float b, float c)
{
x = a;
y = b;
z = c;
}
vec31()
{
}
float x;
float y;
float z;
}vec3;
std::vector<vec3> ListToVectorFloat(PyObject *pTupleValue)
{
std::vector<vec3> vecData;
do
{
if (!pTupleValue)
{
break;
}
if (!PyList_Check(pTupleValue))
{
break;
}
vec3 stFaceNode;
PyObject *pTupleFloat;
int nSize = PyList_Size(pTupleValue);
if (nSize % 3 != 0)
{
break;
}
float x, y, z;
for (int i = 0; i < nSize; i += 3)
{
PyObject *Item = PyList_GetItem(pTupleValue, i);
PyArg_Parse(Item, "f", &x);
Item = PyList_GetItem(pTupleValue, i + 1);
PyArg_Parse(Item, "f", &y);
Item = PyList_GetItem(pTupleValue, i + 2);
PyArg_Parse(Item, "f", &z);
stFaceNode = vec3(x, y, z);
vecData.emplace_back(stFaceNode);
}
} while (false);
return vecData;
}
int main()
{
Py_Initialize();
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./')");
PyObject * pModule = NULL;
PyObject * pFunc = NULL;
pModule = PyImport_ImportModule("test"); //Test:Python文件名
pFunc = PyObject_GetAttrString(pModule, "TestDict"); //Add:Python文件中的函数名
PyObject *pFunc1 = PyObject_GetAttrString(pModule, "TestDictT1"); //Add:Python文件中的函数名
//创建参数:
PyObject *pArgs = PyTuple_New(1);
PyObject *pDict = PyDict_New(); //创建字典类型变量
//PyDict_SetItemString(pDict, "Name", Py_BuildValue("s", "WangYao")); //往字典类型变量中填充数据
//PyDict_SetItemString(pDict, "Age", Py_BuildValue("i", 25)); //往字典类型变量中填充数据
PyTuple_SetItem(pArgs, 0, pDict);//0---序号 将字典类型变量添加到参数元组中
//返回值
PyObject *pReturn = NULL;
// pReturn = PyEval_CallObject(pFunc, pArgs); //调用函数
pReturn = PyEval_CallObject(pFunc1, NULL); //调用函数
//处理返回值:
int size = PyDict_Size(pReturn);
cout << "返回字典的大小为: " << size << endl;
PyObject *pData = PyDict_GetItemString(pReturn, "vertices");
std::vector<vec3> aa = ListToVectorFloat(pData);
PyObject *pType = PyDict_GetItemString(pReturn, "type");
int ntype;
PyArg_Parse(pType, "i", &ntype);
cout << "True Age: " << ntype << endl;
Py_Finalize();
return 0;
}
Python代码
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
import random
import numpy as np
lista = list(np.ones(3*5958).astype(np.float))
def TestDict(dict):
print(dict)
dict["Age"] = 17
return dict
def TestDictT(dict1):
print(dict1)
dict1["type"] = 1
dict1["vertices"] = lista
return dict1
def TestDictT1():
dict1 = {}
dict1["type"] = 0
dict1["vertices"] = lista
print(dict1)
return dict1
TestDictT1()