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]
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章