创建并通过C API从字符串调用Python函数 [英] Create and call python function from string via C API

查看:294
本文介绍了创建并通过C API从字符串调用Python函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有可能从字符串加载一个Python函数,然后调用带参数的功能,得到返回值?

我使用Python C API从我的C ++应用程序内部运行蟒蛇code。我能够加载使用 PyImport_Import 文件的模块,从得到一个函数对象使用 PyObject_GetAttrString ,和调用具有 PyObject_CallObject 的功能。我想要做的就是从一个字符串,而不是一个文件加载模块/功能。有一些相当于 PyImport_Import 这将让我传递一个字符串,而不是一个文件?我需要将参数传递给我打电话的功能,我需要访问返回值,所以我不能只用 PyRun_SimpleString


修改

我发现越来越转向到 PyRun_String 后,此解决方案。我创建一个新的模块,获得的字典对象,通过沿中调用 PyRun_String 在我的新模块来定义一个函数,然后让一个函数对象中通过 PyObject_CallObject 新创建的函数,并调用它,传递我的ARGS。这是我找到了解决我的问题:
的main.cpp

 
诠释的main()
{
    *的PyObject PNAME,* pModule,* pArgs,* P值,* pFunc;
    的PyObject * pGlobal = PyDict_New();
    *的PyObject pLocal;    //创建一个新的模块对象
    的PyObject * pNewMod = PyModule_New(mymod);    Py_Initialize();
    PyModule_AddStringConstant(pNewMod__file__,);    //从我模块获取字典对象,所以我可以把它传递给PyRun_String
    pLocal = PyModule_GetDict(pNewMod);    //定义我的函数新创建的模块中
    P值= PyRun_String(DEF等等(X):\\ n \\ t打印5 * X \\ n \\ treturn 77 \\ n,Py_file_input,pGlobal,pLocal);
    Py_DECREF(P值);    //获取函数我只是定义一个指针
    pFunc = PyObject_GetAttrString(pNewMod,嗒嗒);    //建立一个元组来保存我的论点(只是4号在这种情况下)
    pArgs = PyTuple_New(1);
    P值= PyInt_FromLong(4);
    PyTuple_SetItem(pArgs,0,P值);    //调用我的函数,它传递数字四
    P值= PyObject_CallObject(pFunc,pArgs);
    Py_DECREF(pArgs);
    的printf(返回VAL:%ld个\\ N,PyInt_AsLong(P值));
    Py_DECREF(P值);    Py_XDECREF(pFunc);
    Py_DECREF(pNewMod);
    Py_Finalize();    返回0;
}


这是我原来的职位的休息,为后人留下了:

下面是我最初做的:
的main.cpp

 
#包括LT&; Python.h>诠释的main()
{
    *的PyObject PNAME,* pModule,* pArgs,* P值,* pFunc;    Py_Initialize();
    PyRun_SimpleString(进口SYS);
    PyRun_SimpleString(sys.path.append(''));
    PNAME = PyString_FromString(ATEST);
    pModule = PyImport_Import(PNAME);
    Py_DECREF(PNAME);    如果(pModule == NULL)
    {
        的printf(PMOD为空\\ n);
        PyErr_Print();
        返回1;
    }    pFunc = PyObject_GetAttrString(pModuledoStuff);
    pArgs = PyTuple_New(1);
    P值= PyInt_FromLong(4);
    PyTuple_SetItem(pArgs,0,P值);    P值= PyObject_CallObject(pFunc,pArgs);
    Py_DECREF(pArgs);
    的printf(返回VAL:%ld个\\ N,PyInt_AsLong(P值));
    Py_DECREF(P值);    Py_XDECREF(pFunc);
    Py_DECREF(pModule);    Py_Finalize();    返回0;
}

atest.py

 
高清doStuff(X):
    打印X为%d \\ n%X
    返回2 * X


解决方案

PyRun_String Python的C API的可能是你在找什么。请参阅: http://docs.python.org/c-api/veryhigh.html

Is it possible to load a python function from a string and then call that function with arguments and get the return value?

I'm using the python C API to run python code from inside my C++ application. I'm able to load a module from a file using PyImport_Import, get a function object from that using PyObject_GetAttrString, and call the function with PyObject_CallObject. What I'd like to do is to load the module/function from a string instead of a file. Is there some equivalent to PyImport_Import which would allow me to pass it a string instead of a file? I need to pass arguments to the function I'm calling and I need access to the return value, so I can't just use PyRun_SimpleString.


Edit:

I found this solution after getting turned on to PyRun_String. I'm creating a new module, getting its dictionary object, passing that along in a call to PyRun_String to define a function in my new module, then getting a function object for that newly created function and calling it via PyObject_CallObject, passing my args. This is what I've found to solve my problem: main.cpp


int main()
{
    PyObject *pName, *pModule, *pArgs, *pValue, *pFunc;
    PyObject *pGlobal = PyDict_New();
    PyObject *pLocal;

    //Create a new module object
    PyObject *pNewMod = PyModule_New("mymod");

    Py_Initialize();
    PyModule_AddStringConstant(pNewMod, "__file__", "");

    //Get the dictionary object from my module so I can pass this to PyRun_String
    pLocal = PyModule_GetDict(pNewMod);

    //Define my function in the newly created module
    pValue = PyRun_String("def blah(x):\n\tprint 5 * x\n\treturn 77\n", Py_file_input, pGlobal, pLocal);
    Py_DECREF(pValue);

    //Get a pointer to the function I just defined
    pFunc = PyObject_GetAttrString(pNewMod, "blah");

    //Build a tuple to hold my arguments (just the number 4 in this case)
    pArgs = PyTuple_New(1);
    pValue = PyInt_FromLong(4);
    PyTuple_SetItem(pArgs, 0, pValue);

    //Call my function, passing it the number four
    pValue = PyObject_CallObject(pFunc, pArgs);
    Py_DECREF(pArgs);
    printf("Returned val: %ld\n", PyInt_AsLong(pValue));
    Py_DECREF(pValue);

    Py_XDECREF(pFunc);
    Py_DECREF(pNewMod);
    Py_Finalize();

    return 0;
}


Here is the rest of my original post, left for posterity:

Here's what I was doing originally: main.cpp:


#include <Python.h>

int main()
{
    PyObject *pName, *pModule, *pArgs, *pValue, *pFunc;

    Py_Initialize();
    PyRun_SimpleString("import sys");
    PyRun_SimpleString("sys.path.append('')");
    pName = PyString_FromString("atest");
    pModule = PyImport_Import(pName);
    Py_DECREF(pName);

    if(pModule == NULL)
    {
        printf("PMod is null\n");
        PyErr_Print();
        return 1;
    }

    pFunc = PyObject_GetAttrString(pModule, "doStuff");
    pArgs = PyTuple_New(1);
    pValue = PyInt_FromLong(4);
    PyTuple_SetItem(pArgs, 0, pValue);

    pValue = PyObject_CallObject(pFunc, pArgs);
    Py_DECREF(pArgs);
    printf("Returned val: %ld\n", PyInt_AsLong(pValue));
    Py_DECREF(pValue);

    Py_XDECREF(pFunc);
    Py_DECREF(pModule);

    Py_Finalize();

    return 0;
}

And atest.py:


def doStuff( x):
    print "X is %d\n" % x
    return 2 * x

解决方案

PyRun_String in the Python C API is probably what you're looking for. See: http://docs.python.org/c-api/veryhigh.html

这篇关于创建并通过C API从字符串调用Python函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆