简述
- 主流方法将python程序编程文本形式的动态链接库,在c/c++程序中调用其中定义的函数
- 本质上是在 c++ 中启动了一个 python 解释器,由解释器对 python 相关的代码进行执行,执行完毕后释放资源,达到调用目的
实现
链接到Python调用库
- 检查Python 安装目录下已经包含头文件( 就是c++里 需要include 的目录)和库文件 ( Windows 下为 python27.lib)
直接调用 Python 语句
#include "python/Python.h"
int main()
{
Py_Initialize();
PyRun_SimpleString("print 'hello'");
Py_Finalize();
}
无参python函数调用
def say():
print("hello")
#include <Python.h>
#include <iostream>
using namespace std;
int main(){
Py_Initialize();
if(!Py_IsInitialized()){
cout << "python init fail" << endl;
return 0;
}
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./script')");
PyObject* pModule = PyImport_ImportModule("sayhello");
if( pModule == NULL ){
cout <<"module not found" << endl;
return 1;
}
PyObject* pFunc = PyObject_GetAttrString(pModule, "say");
if( !pFunc || !PyCallable_Check(pFunc)){
cout <<"not found function add_num" << endl;
return 0;
}
PyObject_CallObject(pFunc, NULL);
Py_Finalize();
return 0;
}
有参python函数调用
def AdditionFc(a, b):
print("Now is in python module")
print("{} + {} = {}".format(a, b, a+b))
return a + b
#include<Python.h>
#include <iostream>
using namespace std;
int main()
{
Py_Initialize();
PyObject* pModule = NULL;
PyObject* pFunc = NULL;
PyObject* pName = NULL;
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./')");
pModule = PyImport_ImportModule("myadd");
pFunc = PyObject_GetAttrString(pModule, "AdditionFc");
if( !pFunc || !PyCallable_Check(pFunc)){
cout <<"not found function AdditionFc" << endl;
return 0;
}
PyObject* pArgs = PyTuple_New(2);
PyTuple_SetItem(pArgs, 0, Py_BuildValue("i", 2));
PyTuple_SetItem(pArgs, 1, Py_BuildValue("i", 4));
PyObject* pReturn = PyEval_CallObject(pFunc, pArgs);
int nResult;
PyArg_Parse(pReturn, "i", &nResult);
cout << "return result is " << nResult << endl;
Py_Finalize();
}
编译
API
void Py_Initialize(void)
int Py_IsInitialized(void)
void Py_Finalize()
int PyRun_SimpleString(const char *command)
PyObject* PyImport_ImportModule(char *name)
PyObject* PyModule_GetDict( PyObject *module)
PyObject* PyRun_String(const char* str, int start,PyObject* globals, PyObject* locals)
int PyArg_Parse(PyObject* args, char* format, …)
PyObject* PyObject_GetAttrString(PyObject *o, char*attr_name)
PyObject* Py_BuildValue(char* format, …)
PyObject* PyEval_CallObject(PyObject* pfunc, PyObject*pargs)
例子
void TestF1(void)
{
PyObject* pModule = NULL;
PyObject* pFunc = NULL;
PyObject* pArg = NULL;
pModule = PyImport_ImportModule("demo1");
pFunc = PyObject_GetAttrString(pModule, "Hello");
pArg = Py_BuildValue("(s)", "my is c++ test!");
PyEval_CallObject(pFunc, pArg);
pFunc = PyObject_GetAttrString(pModule, "Add");
pArg = Py_BuildValue("(i,i)", 10, 25);
PyEval_CallObject(pFunc, pArg);
}
void TestF2(void)
{
PyObject* pModule = NULL;
PyObject* pFunc = NULL;
PyObject* pArg = NULL;
pModule = PyImport_ImportModule("demo2");
PyObject* pyFunc_printList = PyObject_GetAttrString(pModule, "printList");
if (pModule && PyCallable_Check(pyFunc_printList))
{
PyObject* pyParams = PyList_New(0);
PyList_Append(pyParams, Py_BuildValue("d", 5));
PyList_Append(pyParams, Py_BuildValue("i", 2));
PyList_Append(pyParams, Py_BuildValue("i", 6));
PyList_Append(pyParams, Py_BuildValue("i", 8));
PyObject* args = PyTuple_New(1);
PyTuple_SetItem(args, 0, pyParams);
PyEval_CallObject(pyFunc_printList, args);
}
}
void TestF3(void)
{
PyObject* pModule = NULL;
PyObject* pFunc = NULL;
PyObject* pArg = NULL;
PyObject* pClass = NULL;
PyObject* pObject = NULL;
pModule = PyImport_ImportModule("demo3");
pClass = PyObject_GetAttrString(pModule, "Person");
pArg = PyTuple_New(1);
PyTuple_SetItem(pArg, 0, Py_BuildValue("s", "Class:Jacky"));
pObject = PyEval_CallObject(pClass, pArg);
pFunc = PyObject_GetAttrString(pObject, "printName");
PyEval_CallObject(pFunc, NULL);
}
void TestF4(void)
{
PyObject* pModule = PyImport_ImportModule("demo4");
PyObject* pyFunc_mix = PyObject_GetAttrString(pModule, "mix");
if (pModule && PyCallable_Check(pyFunc_mix))
{
PyObject* pyParams = PyTuple_New(2);
PyTuple_SetItem(pyParams, 0, Py_BuildValue("i", 5));
PyTuple_SetItem(pyParams, 1, Py_BuildValue("i", 2));
int r1 = 0, r2 = 0;
PyObject* pyValue = PyObject_CallObject(pyFunc_mix, pyParams);
PyArg_ParseTuple(pyValue, "i|i", &r1, &r2);
if (pyValue)
{
printf("%d %d\n", r1, r2);
}
}
}
void TestF5(void)
{
if (_import_array() < 0)
{
PyErr_Print();
PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import");
}
PyObject* pModule = NULL;
PyObject* pFunc = NULL;
pModule = PyImport_ImportModule("demo5");
PyObject* pyFunc_printList = PyObject_GetAttrString(pModule, "printList");
float buf[2][3];
buf[0][0] = 0;
buf[0][1] = 1.233;
buf[0][2] = 2.222;
buf[1][0] = 4.222;
buf[1][1] = 5.333;
buf[1][2] = 6.333;
PyObject* pArgs = PyTuple_New(1);
npy_intp dims[2]={2,3};
int ND = 2;
PyObject* pPyArray = PyArray_SimpleNewFromData(ND, dims, NPY_FLOAT, buf);
PyTuple_SetItem(pArgs, 0, pPyArray);
PyEval_CallObject(pyFunc_printList, pArgs);
}