转:python嵌入代码示例

#include <Python.h>

int
main(int argc, char *argv[])
{
    PyObject *pName, *pModule, *pDict, *pFunc;
    PyObject *pArgs, *pValue;
    int i;

    if (argc < 3) {
        fprintf(stderr,"Usage: call pythonfile funcname [args]n");
        return 1;
    }

    Py_Initialize();
    pName = PyString_FromString(argv[1]);
    /* Error checking of pName left out */

    pModule = PyImport_Import(pName);
    Py_DECREF(pName);

    if (pModule != NULL) {
        pFunc = PyObject_GetAttrString(pModule, argv[2]);
        /* pFunc is a new reference */

        if (pFunc && PyCallable_Check(pFunc)) {
            pArgs = PyTuple_New(argc - 3);
            for (i = 0; i < argc - 3; ++i) {
                pValue = PyInt_FromLong(atoi(argv[i + 3]));
                if (!pValue) {
                    Py_DECREF(pArgs);
                    Py_DECREF(pModule);
                    fprintf(stderr, "Cannot convert argumentn");
                    return 1;
                }
                /* pValue reference stolen here: */
                PyTuple_SetItem(pArgs, i, pValue);
            }
            pValue = PyObject_CallObject(pFunc, pArgs);
            Py_DECREF(pArgs);
            if (pValue != NULL) {
                printf("Result of call: %ldn", PyInt_AsLong(pValue));
                Py_DECREF(pValue);
            }
            else {
                Py_DECREF(pFunc);
                Py_DECREF(pModule);
                PyErr_Print();
                fprintf(stderr,"Call failedn");
                return 1;
            }
        }
        else {
            if (PyErr_Occurred())
                PyErr_Print();
            fprintf(stderr, "Cannot find function \"%s\"n", argv[2]);
        }
        Py_XDECREF(pFunc);
        Py_DECREF(pModule);
    }
    else {
        PyErr_Print();
        fprintf(stderr, "Failed to load \"%s\"n", argv[1]);
        return 1;
    }
    Py_Finalize();
    return 0;
}

这段代码从argv[1]中载入Python脚本,并且调用argv[2]中的函数,整数型的参数则是从argv数组后面得来的。如果编译和链接这个程序,执行如下脚本:

def multiply(a,b):
    print "Will compute",a,"times",b
    c=0
    for i in range(0,a)
        c=c+b
    return c

结果将是:

$ call multiply multiply 3 2
Will compute 3 times 2
Result of call: 6

虽然这个程序的代码挺多的,但是大部分其实都是做数据转换和错误报告。主要关于嵌入Python的开始于:

Py_Initialize();
pName=PyString_FromString(argv[1]);
/* Error checking of pName left out */
pModule=PyImport_Import(pName);

初始化解释器之后,使用 PyImport_Import() 导入模块。这个函数需要字符串作为参数,使用 PyString_FromString() 来构造:

pFunc=PyObject_GetAttrString(pModule,argv[2]);
/* pFunc is a new reference */
if (pFunc && PyCallable_Check(pFunc)) {
    ...
}
Py_XDECREF(pFunc);

载入了模块以后,就可以通过 PyObject_GetAttrString() 来获取对象。如果名字存在并且可以执行则可以安全的调用它。程序随后构造参数元组,然后执行调用:

pValue=PyObject_CallObject(pFunc,pArgs);

函数调用之后,pValue要么是NULL,要么是返回值的对象引用。注意在检查完返回值之后要释放引用。

另一个:

1.     安装   Python   到   d:\python23
2.     新建一个VC项目,   在   Project   Setting     中,把   d:\python\include   加入“其他头文件”哪一项,把   d:\python\libs   加入   link   的附加目录里。
3.     在主文件里这样写:  

#include   <python.h>       //   PYthon   头文件
#include   <stdio.h>


void   main(void)
{
Py_Initialize();                       //python   解释器的初始化
if(!Py_IsInitialized())
{
printf( "can 't   init   python ");
return;
}


PyRun_SimpleString( "import   sys ");
PyRun_SimpleString( "sys.path.append( './ ') ");

PyObject   *pName,*pModule,*pDict,*pFunc,*pArgs,*pRes;

pName   =   PyString_FromString( "pytest ");         //   这个就是你要嵌入的python   文件名

pModule   =   PyImport_Import(pName);
if(!pModule)
{
printf( "can 't   find   pytest.py ");
getchar();
return   ;

}

pDict   =   PyModule_GetDict(pModule);     //   得到python模块中的函数表
if(!pDict)
return;

pFunc   =   PyDict_GetItemString(pDict, "add ");
if(!pFunc   ||   !PyCallable_Check(pFunc))
{
printf( "can 't   find   function   [add] ");
getchar();
return;
}

*pArgs;
                    //     添参数
pArgs   =   PyTuple_New(2);
PyTuple_SetItem(pArgs,0,Py_BuildValue( "l ",343));
PyTuple_SetItem(pArgs,1,Py_BuildValue( "l ",42356));

PyObject_CallObject(pFunc   ,   pArgs);           //   调用   python   程序


pFunc   =   PyDict_GetItemString(pDict, "str_find ");
if(!pFunc   ||   !PyCallable_Check(pFunc))
{
printf( "can 't   find   function   [add] ");
getchar();
return;
}
                 
                  //   另外一个函数例子,演示了如何向   python   传递参数,和如何传回   C++
pArgs   =   PyTuple_New(2);
PyTuple_SetItem(pArgs,0,Py_BuildValue( "s ", "abcdef "));
PyTuple_SetItem(pArgs,1,Py_BuildValue( "s ", "de "));

long   ret_val   =   PyInt_AsLong(PyObject_CallObject(pFunc   ,   pArgs));

printf( "%d\n ",ret_val);


Py_DECREF(pModule);


Py_Finalize();                       //   清除
getchar();
}  

//   -----------------------------------------
python   文件     pytest.py
def   add(a,b):
        print   "in   python   function   add "
        print   a+b
        return

def   str_find(str1,str2):
        print   "str1: ",str1
        print   "str2: ",str2
        return   str1.rfind(str2)

posted @ 2011-08-30 11:20  熊爸爸  阅读(802)  评论(0)    收藏  举报