GVJ C/C++ 调用 Python脚本

本文从WordPress迁移而来, 查看全部WordPress迁移文章

需求背景:可以用c++或者python写的一个小模块,但是c++写起来太麻烦,另外不见得两者有什么性能差别,所以用python写,用c++调用这个小模块,给py模块传递参数,然后获得返回值

Python 版本 2.7: 官方文档 Python C API

转的两篇文章:

准备两个py脚本用来测试

  • sample.py
1
2
3
4
5
6
7
8
9
10
def addFunc(x, y):
return x + y

a = 1
b = 2
print "a + b = ", a+b

x = 1
y = 2
print "addFunc: x + y = ", addFunc(x, y)
  • call.py
1
2
3
4
5
def printFunc():
print "python: printFunc"

def addFunc(a,b):
return a + b

C++测试代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include <cstdio>
#include <iostream>
#include <cstring>
#include <unistd.h>
#include <fcntl.h>
#include <python2.7/Python.h>

using namespace std;

int main() {
int fd;
size_t size;
char text[10000];

Py_Initialize();

// 必须的,更改环境变量
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./')");

if (Py_IsInitialized() == 0) {
puts("Py_Initlialize failed");
return 0;
}

/************************************************/
// 读取一个py文件里面的语句,然后执行
fd = open("sample.py", O_RDONLY|O_EXCL);
size = read(fd, text, 10000);
text[size] = '\0';
close(fd);

int res = PyRun_SimpleString(text);
/************************************************/

/************************************************/
// 有些时候我们需要在py文件里面写一些模块
// 然后调用这些模块,另外我们经常需要传递参数给它们

PyObject *call = PyImport_ImportModule("call");
// 下面这两句话和上面的等价
//PyObject *pName = PyString_FromString("call");
//PyObject *call = PyImport_Import(pName);
if (!call) {
puts("PyImport_ImportModule failed");
return 0;
}

// 调用这个函数,这个函数是不需要参数的(传递NULL)
PyObject *printFunc = PyObject_GetAttrString(call, "printFunc");
if (!printFunc) {
puts("PyObject_GetAttrString, printFunc failed");
return 0;
}
PyObject *prun = PyEval_CallObject(printFunc, NULL);

// 调用这个函数,这个函数是需要参数的,也有返回值
int a = 1, b = 2, sum = -1;
PyObject *addFunc = PyObject_GetAttrString(call, "addFunc");
if (!addFunc) {
puts("PyObject_GetAttrString addFunc failed");
return 0;
}
// 设置参数
PyObject *arg = Py_BuildValue("(i,i)", a, b);
PyObject *result = PyEval_CallObject(addFunc, arg);
// 解析返回值
PyArg_Parse(result, "i", &sum);
printf("sum = %d\n", sum);
/************************************************/


Py_Finalize();
return 0;
}

此文不涉及调用python类的内容