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] |