由于Python功能强大并且各种应用程序库十分丰富,它常常可以以一种简单的方式来完成C/C++比较难实现的功能。Python/C API可以使得C/C++程序员在他们的程序中嵌入Python程序,使得开发的灵活性和简易性大大提高。在这里我以python 2.5版本举一个小例子来简单讲述一下Python/C API的用法,如果大家有兴趣可以参见官方文档来深入学习:
在code之前需要先做一些准备:
1. 把python的include和libs目录分别加到vc的include和lib directories中去。
2. 另外,由于python没有提供debug lib,具体地说,就是没有提供python25_d.lib了,所以默认只能在Release下运行。
3. 可以自己编译python的源代码来得到python25_d.lib。
4. 或者,想要在debug下运行程序的话,你要把pyconfig.h(在python25/include/目录下)的大概是在283行,
5. 把pragma comment(lib,"python25_d.lib")改成pragma comment(lib,"python25.lib"),让python都使用非debug lib.
我们需要嵌套的这段Python代码用于遍历目录得到其下的所有文件。将这个.py文件copy到工程目录中。
1: #-*- coding:gbk -*-
2:
3: import os,sys
4:
5: def walk_dir(dirpath,dirfile):
6: if not os.path.exists(dirpath) :
7: print '%s does not exits, please try again !' %dirpath
8: return -1
9:
10: dirtuple=[dirs for dirs in os.walk(dirpath)][0]
11: #print 'dirtuple is',dirtuple
12: root=dirtuple[0]
13: #print 'root is',root
14: if root[len(root)-1] != os.sep :
15: root+=os.sep
16:
17: f=file(dirfile,'a')
18: for files in dirtuple[2]:
19: f.write('%s\n' % (root+files))
20: f.flush() #avoid buffer overflow
21: f.close()
22:
23: for dirs in dirtuple[1]:
24: walk_dir(root+dirs,dirfile)
25:
26: return 1
27:
下面这段代码中的注释简要介绍了常用的Python/C API
1: #include <string>
2: #include <iostream>
3: #include <Python.h>
4:
5: //Python c api使用方法
6:
7: using namespace std;
8:
9: string GetPyFun(string s1,string s2)
10: {
11: // void Py_Initialize( )
12: //初始化Python解释器,在C++程序中使用其它Python/C API之前,必须调用此函数,如果调用失败,将产生一个致命的错误
13: Py_Initialize();
14:
15: //定义变量
16: PyObject * pModule = NULL;
17: PyObject * pFunc = NULL;
18: PyObject * pArg = NULL;
19: PyObject * result;
20: char *resultStr = "";
21:
22: //int PyRun_SimpleString( const char *command)
23: //直接执行一段Python代码,就好象是在__main__ 函数里面执行一样。
24: //PyRun_SimpleString("import sys");
25: //PyRun_SimpleString("sys.path.append('C:\\Documents and Settings\\Administrator\\My Documents\\Visual Studio 2005\\Projects\\hello\\hello')");
26:
27: //PyObject* PyImport_ImportModule(char *name)
28: //导入一个Python模块,参数name可以是*.py文件的文件名。相当于Python内建函数__import__()
29: pModule =PyImport_ImportModule("hello");//这里是要调用的文件名
30:
31: //PyObject* PyObject_GetAttrString(PyObject *o, char *attr_name)
32: //返回模块对象o中的attr_name属性或函数,相当于Python中表达式语句:o.attr_name
33: pFunc= PyObject_GetAttrString(pModule, "Hello");
34:
35: //PyObject* Py_BuildValue( char *format, ...)
36: //format以tuple的形式指定,一个参数就是(i)
37: //构建一个参数列表,把C类型转换为Python对象,使Python可以使用C类型数据
38: pArg= Py_BuildValue("(s,s)", s1.c_str(),s2.c_str());
39:
40: //pParm = PyTuple_New(2);
41: //PyTuple_SetItem(pParm, 0, Py_BuildValue("s", csEntity));
42: //PyTuple_SetItem(pParm, 1, Py_BuildValue("s", csEntity));
43:
44: //PyObject* PyEval_CallObject(PyObject* pfunc, PyObject* pargs)
45: //用于调用Python函数
46: //此函数接受两个PyObject*形参
47: //pfunc是要被调用的Python函数,通常可由PyObject_GetAttrString获得
48: //pargs是函数的参数列表,通常可由Py_BuildValue获得
49: result = PyEval_CallObject(pFunc, pArg);
50:
51: //int PyArg_Parse( PyObject *args, char *format, ...)
52: //解构Python数据为C的类型,这样C程序中才可以使用Python里的数据。
53: PyArg_Parse(result, "s", &resultStr);
54:
55: //关闭Python解释器,释放解释器所占用的资源
56: Py_Finalize();
57: return resultStr;
58: }
59:
60: int Walk(const string& s1,const string& s2)
61: {
62: // void Py_Initialize( )
63: //初始化Python解释器,在C++程序中使用其它Python/C API之前,必须调用此函数,如果调用失败,将产生一个致命的错误
64: Py_Initialize();
65:
66: //定义变量
67: PyObject * pModule = NULL;
68: PyObject * pFunc = NULL;
69: PyObject * pArg = NULL;
70: PyObject * result;
71: int reVal = 0;
72:
73: //int PyRun_SimpleString( const char *command)
74: //直接执行一段Python代码,就好象是在__main__ 函数里面执行一样。
75: //PyRun_SimpleString("import sys");
76: //PyRun_SimpleString("sys.path.append('C:\\Documents and Settings\\Administrator\\My Documents\\Visual Studio 2005\\Projects\\hello\\hello')");
77:
78: //PyObject* PyImport_ImportModule(char *name)
79: //导入一个Python模块,参数name可以是*.py文件的文件名。相当于Python内建函数__import__()
80: pModule =PyImport_ImportModule("walkdir");//这里是要调用的文件名
81:
82: //PyObject* PyObject_GetAttrString(PyObject *o, char *attr_name)
83: //返回模块对象o中的attr_name属性或函数,相当于Python中表达式语句:o.attr_name
84: pFunc= PyObject_GetAttrString(pModule, "list_dir");
85:
86: //PyObject* Py_BuildValue( char *format, ...)
87: //format以tuple的形式指定,一个参数就是(i)
88: //构建一个参数列表,把C类型转换为Python对象,使Python可以使用C类型数据
89: pArg= Py_BuildValue("(s,s)", s1.c_str(),s2.c_str());
90:
91: //pParm = PyTuple_New(2);
92: //PyTuple_SetItem(pParm, 0, Py_BuildValue("s", csEntity));
93: //PyTuple_SetItem(pParm, 1, Py_BuildValue("s", csEntity));
94:
95: //PyObject* PyEval_CallObject(PyObject* pfunc, PyObject* pargs)
96: //用于调用Python函数
97: //此函数接受两个PyObject*形参
98: //pfunc是要被调用的Python函数,通常可由PyObject_GetAttrString获得
99: //pargs是函数的参数列表,通常可由Py_BuildValue获得
100: result = PyEval_CallObject(pFunc, pArg);
101:
102: //int PyArg_Parse( PyObject *args, char *format, ...)
103: //解构Python数据为C的类型,这样C程序中才可以使用Python里的数据。
104: PyArg_Parse(result, "i", &reVal);
105:
106: //关闭Python解释器,释放解释器所占用的资源
107: Py_Finalize();
108: return reVal;
109: }
110:
111: int main()
112: {
113: //string re=GetPyFun("hello","world");
114: //cout<<"\n"<<re<<endl;
115:
116: cout<<"enter a path and a filename:"<<endl;
117: string path,dir;
118: cin>>path>>dir;
119: int re=Walk(path,dir);
120:
121: return 0;
122: }