【原】Python/C API使用方法简介 (在C/C++中嵌入Python)

由于Python功能强大并且各种应用程序库十分丰富,它常常可以以一种简单的方式来完成C/C++比较难实现的功能。Python/C API可以使得C/C++程序员在他们的程序中嵌入Python程序,使得开发的灵活性和简易性大大提高。在这里我以python 2.5版本举一个小例子来简单讲述一下Python/C API的用法,如果大家有兴趣可以参见官方文档来深入学习:

http://docs.python.org/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: }
posted @ 2011-02-04 00:33  Allen Sun  阅读(6423)  评论(0编辑  收藏