c++ 调用python 安装python 调用python 简单demo

c++ 调用 Python


参考文档

安装Python

首先安装Python,并记录头文件和库文件的位置。
编译的时候用到;
例:

g++ -o sample  sample.cpp -I /usr/include/python3.6/ -L /usr/lib/python3.6/config-3.6m-x86_64-linux-gnu -lpython3.6

写一个简单的python函数

例:

#coding = utf-8
#!/usr/bin/python
#Filename:TestModule.py
def Hello(s):
    print ("Hello World")
    print(s)

def Add(a, b):
    print('a=', a)
    print ('b=', b)
    return a + b

def Add2(a,b,c):
    return a + b + c

class Test:
    def __init__(self):
        print("Init")
    def SayHello(self, name):
        print ("Hello,", name)
        return name

写c++ 程序

第一步 添加python的声明 和设置Python的安装路径

#include "Python.h"
Py_SetPythonHome(L"/usr/local/Anaconda3/envs/pytorch_gpu"); //非必须

第二步:初始化python接口

	//初始化Python
    Py_Initialize();
	if (!Py_IsInitialized())
	{
		return -1;
	}

第三步:初始化python系统文件路径,保证可以访问到 .py文件

PyRun_SimpleString("import sys");  
PyRun_SimpleString("sys.path.append('./')");  

第四步:引用模板

PyObject *pModule = PyImport_ImportModule("TestModule");

第五步:调用函数

    //直接获取模板中的函数
    PyObject *pFunc = PyObject_GetAttrString(pModule, "Hello");

    //参数类型转换,传递一个字符串。将c/c++类型的字符串转换为python类型,元组中的python类型查看python文档
    PyObject *pArg = Py_BuildValue("(s)", "Hello World");

    //调用直接获得的函数,并传递参数
    PyEval_CallObject(pFunc, pArg);

第六步:结束python接口初始化

Py_Finalize();

demo

#include "Python.h"
#include <stdio.h>

int main(int argc, char *argv[])
{
	//初始化Python
    Py_Initialize();
	if (!Py_IsInitialized())
	{
		return -1;
	}

    //直接运行Python代码
    PyRun_SimpleString("print('----------Python Start')");

    //引入Python文件的路径
    PyRun_SimpleString("import sys");  
    PyRun_SimpleString("sys.path.append('./python/')"); 

    //引入模板
    //printf("PyImport_ImportModule\n");
    PyObject *pModule = PyImport_ImportModule("TestModule");

    //获取模板字典属性
    PyObject *pDict = PyModule_GetDict(pModule);

    //直接获取模板中的函数
    PyObject *pFunc = PyObject_GetAttrString(pModule, "Hello");

    //参数类型转换,传递一个字符串。将c/c++类型的字符串转换为python类型,元组中的python类型查看python文档
    PyObject *pArg = Py_BuildValue("(s)", "Hello World");

    //调用直接获得的函数,并传递参数
    PyEval_CallObject(pFunc, pArg);

    printf("-----------------\n");

    //从字典属性中获取函数
    pFunc = PyDict_GetItemString(pDict, "Add");
    //参数类型转换,传递两个整型参数
    pArg = Py_BuildValue("(i, i)", 1, 2);

    //调用函数,并得到python类型的返回值
    PyObject *result = PyEval_CallObject(pFunc, pArg);
    //c用来保存c/c++类型的返回值
    int c;
    //将python类型的返回值转换为c/c++类型
    PyArg_Parse(result, "i", &c);
    //输出返回值
    printf("a+b=%d\n", c);

    printf("------------------\n");
    PyObject *pFunc2 = PyObject_GetAttrString(pModule, "Add2");

    //创建参数:
	PyObject *pArgs = PyTuple_New(3);//函数调用的参数传递均是以元组的形式打包的,2表示参数个数
	PyTuple_SetItem(pArgs, 0, Py_BuildValue("i", 6));//0--序号,i表示创建int型变量
	PyTuple_SetItem(pArgs, 1, Py_BuildValue("i", 8));//1--序号
    PyTuple_SetItem(pArgs, 2, Py_BuildValue("i", 10));//2--序号
	//返回值
	PyObject* pReturn = NULL;
	pReturn = PyEval_CallObject(pFunc2, pArgs);//调用函数
	//将返回值转换为int类型
	int tmpresult;
	PyArg_Parse(pReturn, "i", &tmpresult);     //i表示转换成int型变量
	printf("6+8+10 = %d\n",tmpresult);

    printf("------------------\n");

    //通过字典属性获取模块中的类
    PyObject *pClass = PyDict_GetItemString(pDict, "Test");

    //实例化获取的类
    PyObject *pInstance = PyInstanceMethod_New(pClass);
    //调用类的方法
    //result = PyObject_CallMethod(pInstance, "SayHello", "(Os)", pInstance, "Charity");
    result = PyObject_CallMethod(pClass, "SayHello", "(Os)", pInstance, "Charity");
    //输出返回值
    char* name=NULL;
    PyArg_Parse(result, "s", &name);
    printf("%s\n", name);

    //释放python
    Py_Finalize();
    getchar();
    return 0;

}


参数传递

参数为空

pFunc = PyObject_GetAttrString(pModule, "Hellotest");
PyEval_CallObject(pFunc, NULL);

参数不为空

PyObject_CallMethod(pClass, “class_method”, “O”, pInstance)

参数分别为 PyObject(类),string(类方法),string(O表示参数为PyObject) ,PyObject(类实例)

PyObject_CallFunction(pFun, “O”, pyores)

参数分别为 PyObject(函数),string(O表示参数为PyObject) ,PyObject(函数中使用的参数)

多个参数:

PyObject_CallFunction(pFun, “OO…O”, PyObject 1,PyObject 2…PyObject n)

中间的O可替换成参数类型说明符中的任意一个,比如字符串s,int型变量i等等

元组传参

//创建一个元组
PyObject *pArgs = PyTuple_New(3);
PyTuple_SetItem(pArgs, 0, Py_BuildValue(“i”, 1));//0—序号 i表示创建int型变量
PyTuple_SetItem(pArgs, 1, Py_BuildValue(“i”, 2));
PyTuple_SetItem(pArgs, 2, Py_BuildValue(“i”, 3));

PyEval_CallObject(pFunc, pArgs); //调用函数,pArgs元素个数与被调函数参数个数一致

字典传参

PyObject *pDict = PyDict_New(); //创建字典类型变量
PyDict_SetItemString(pDict, “Name”, Py_BuildValue(“s”, “Zhangsan”)); //往字典类型变量中填充数据
PyDict_SetItemString(pDict, “Address”, Py_BuildValue(“s”, “BeiJing”));

//将上述字典赋值给元组
PyObject *pArgs = PyTuple_New(1);
PyTuple_SetItem(pArgs, 0, pDict) 

参数类型对照表

Python c++
s (string) [char *]
s# (string) [char *, int]
z (string or None) [char *]
z# (string or None) [char *, int]
u (Unicode string) [Py_UNICODE *]
u# (Unicode string) [Py_UNICODE *, int]
i (integer) [int]
b (integer) [char]
h (integer) [short int]
l (integer) [long int]
B (integer) [unsigned char]
H (integer) [unsigned short int]
I (integer/long) [unsigned int]
k (integer/long) [unsigned long]
L (long) [PY_LONG_LONG]
K (long) [unsigned PY_LONG_LONG]
n (int) [Py_ssize_t]
c (string of length 1) [char]
d (float) [double]
f (float) [float]
D (complex) [Py_complex *]
O (object) [PyObject *]
S (object) [PyObject *]
N (object) [PyObject *]
O& (object) [converter, anything]
(items) (tuple) [matching-items]
[items] (list) [matching-items]
{items} (dictionary) [matching-items]
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章