Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/164.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从C/C+;调用python方法+;,并提取其返回值_C++_Python_C_Python C Api_Python Embedding - Fatal编程技术网

C++ 从C/C+;调用python方法+;,并提取其返回值

C++ 从C/C+;调用python方法+;,并提取其返回值,c++,python,c,python-c-api,python-embedding,C++,Python,C,Python C Api,Python Embedding,我想从C调用python模块中定义的自定义函数。我有一些初步的代码来实现这一点,但它只是将输出打印到stdout mytest.py import math def myabs(x): return math.fabs(x) 测试.cpp #include <Python.h> int main() { Py_Initialize(); PyRun_SimpleString("import sys; sys.path.append('.')");

我想从C调用python模块中定义的自定义函数。我有一些初步的代码来实现这一点,但它只是将输出打印到stdout

mytest.py

import math

def myabs(x):
    return math.fabs(x)
测试.cpp

#include <Python.h>

int main() {
    Py_Initialize();
    PyRun_SimpleString("import sys; sys.path.append('.')");
    PyRun_SimpleString("import mytest;");
    PyRun_SimpleString("print mytest.myabs(2.0)");
    Py_Finalize();

    return 0;
}
#包括
int main(){
Py_初始化();
PyRun_SimpleString(“import sys;sys.path.append('.')”;
PyRun_SimpleString(“导入mytest;”);
PyRun_SimpleString(“print mytest.myabs(2.0)”;
Py_Finalize();
返回0;
}

如何将返回值提取到C double中并在C中使用?

您必须以某种方式提取python方法,并使用
PyObject\u CallObject()
运行它。为此,您可以向Python提供一种设置函数的方法,如示例所示。

调用Python函数并检索结果的完整示例位于:

#包括
int
main(int argc,char*argv[])
{
PyObject*pName、*pModule、*pDict、*pFunc;
PyObject*pArgs,*pValue;
int i;
如果(argc<3){
fprintf(stderr,“用法:调用pythonfile funcname[args]\n”);
返回1;
}
Py_初始化();
pName=PyString_FromString(argv[1]);
/*检查遗漏的pName时出错*/
pModule=PyImport\u Import(pName);
Py_DECREF(pName);
if(pModule!=NULL){
pFunc=PyObject_GetAttrString(pModule,argv[2]);
/*pFunc是一个新的参考*/
if(pFunc&&PyCallable_检查(pFunc)){
pArgs=PyTuple_New(argc-3);
对于(i=0;i
如果将返回值赋给变量,则可以使用PyEval\u GetGlobals()和PyDict\u GetItemString()之类的方法来获取PyObject。从那里,PyNumber\u Float可以得到您想要的值


我建议浏览整个API—当您看到可用的不同方法时,某些事情会变得很明显,很可能有一种比我描述的更好的方法。

如前所述,使用PyRun_SimpleString似乎是个坏主意

您肯定应该使用C-API()提供的方法

阅读导言是理解其工作方式的第一件事

首先,您必须了解PyObject,它是C API的基本对象。它可以表示任何类型的python基本类型(string、float、int等)

有许多函数可以将python字符串转换为char*或将PyFloat转换为double

首先,导入您的模块:

PyObject* myModuleString = PyString_FromString((char*)"mytest");
PyObject* myModule = PyImport_Import(myModuleString);
然后获取对函数的引用:

PyObject* myFunction = PyObject_GetAttrString(myModule,(char*)"myabs");
PyObject* args = PyTuple_Pack(1,PyFloat_FromDouble(2.0));
然后得到你的结果:

PyObject* myResult = PyObject_CallObject(myFunction, args)
回到双人间:

double result = PyFloat_AsDouble(myResult);
显然,您应该检查错误(参见Mark Tolonen给出的链接)


如果你有任何问题,不要犹豫。祝好运。

< P>我已经使用Boost到Python的Python做了C++ [这个工作C模块应该帮助] < /P>
#include <boost/python.hpp>

void main()
{
using namespace boost::python;
 Py_Initialize();
 PyObject* filename = PyString_FromString((char*)"memory_leak_test");
     PyObject* imp = PyImport_Import(filename);
     PyObject* func = PyObject_GetAttrString(imp,(char*)"begin");
     PyObject* args = PyTuple_Pack(1,PyString_FromString("CacheSetup"));
     PyObject* retured_value = PyObject_CallObject(func, args); // if you have arg
     double retured_value = PyFloat_AsDouble(myResult);
 std::cout << result << std::endl;
 Py_Finalize();
}
#包括
void main()
{
使用名称空间boost::python;
Py_初始化();
PyObject*filename=PyString\u FromString((char*)“内存泄漏测试”);
PyObject*imp=PyImport\u Import(文件名);
PyObject*func=PyObject_GetAttrString(imp,(char*)“begin”);
PyObject*args=PyTuple_Pack(1,PyString_FromString(“CacheSetup”);
PyObject*retured\u value=PyObject\u CallObject(func,args);//如果有arg
double retured_value=PyFloat_AsDouble(myResult);

std::cout这里是我编写的示例代码(在各种在线资源的帮助下),用于向Python代码发送字符串,然后返回值

这是C代码调用函数。C代码:

#include <Python.h>
#include <stdlib.h>
int main()
{
   // Set PYTHONPATH TO working directory
   setenv("PYTHONPATH",".",1);

   PyObject *pName, *pModule, *pDict, *pFunc, *pValue, *presult;


   // Initialize the Python Interpreter
   Py_Initialize();


   // Build the name object
   pName = PyString_FromString((char*)"arbName");

   // Load the module object
   pModule = PyImport_Import(pName);


   // pDict is a borrowed reference 
   pDict = PyModule_GetDict(pModule);


   // pFunc is also a borrowed reference 
   pFunc = PyDict_GetItemString(pDict, (char*)"someFunction");

   if (PyCallable_Check(pFunc))
   {
       pValue=Py_BuildValue("(z)",(char*)"something");
       PyErr_Print();
       printf("Let's give this a shot!\n");
       presult=PyObject_CallObject(pFunc,pValue);
       PyErr_Print();
   } else 
   {
       PyErr_Print();
   }
   printf("Result is %d\n",PyInt_AsLong(presult));
   Py_DECREF(pValue);

   // Clean up
   Py_DECREF(pModule);
   Py_DECREF(pName);

   // Finish the Python Interpreter
   Py_Finalize();


    return 0;
}

我使用命令
gcc call\u function.c-I/usr/include/python2.6-lpython2.6;/a.out
来运行这个过程。我使用的是redhat。我建议使用PyErr\u Print();用于错误检查。

为了防止与其他答案中一样出现额外的.py文件,您只需检索
\uuuu main\uuuu
模块,该模块是通过第一次调用
PyRun\u SimpleString创建的:

PyObject *moduleMainString = PyString_FromString("__main__");
PyObject *moduleMain = PyImport_Import(moduleMainString);

PyRun_SimpleString(
    "def mul(a, b):                                 \n"\
    "   return a * b                                \n"\
);

PyObject *func = PyObject_GetAttrString(moduleMain, "mul");
PyObject *args = PyTuple_Pack(2, PyFloat_FromDouble(3.0), PyFloat_FromDouble(4.0));

PyObject *result = PyObject_CallObject(func, args);

printf("mul(3,4): %.2f\n", PyFloat_AsDouble(result)); // 12

以下是对您的问题的简单而直接的回答:

    #include <iostream>
    #include <Python.h>
    using namespace std;
    int main()
    {
    const char *scriptDirectoryName = "/yourDir";
    Py_Initialize();
    PyObject *sysPath = PySys_GetObject("path");
    PyObject *path = PyString_FromString(scriptDirectoryName);
    int result = PyList_Insert(sysPath, 0, path);
    PyObject *pModule = PyImport_ImportModule("mytest");

    PyObject* myFunction = PyObject_GetAttrString(pModule,(char*)"myabs");
    PyObject* args = PyTuple_Pack(1,PyFloat_FromDouble(-2.0));


    PyObject* myResult = PyObject_CallObject(myFunction, args);
    double getResult = PyFloat_AsDouble(myResult);
    return 0;
    }
#包括
#包括
使用名称空间std;
int main()
{
常量char*scriptDirectoryName=“/yourDir”;
Py_初始化();
PyObject*sysPath=PySys_GetObject(“path”);
PyObject*path=PyString\u FromString(scriptDirectoryName);
int result=PyList_Insert(sysPath,0,path);
PyObject*pModule=PyImport_ImportModule(“mytest”);
PyObject*myFunction=PyObject_GetAttrString(pModule,(char*)“myabs”);
PyObject*args=PyTuple_Pack(1,PyFloat_fromtdouble(-2.0));
PyObject*myResult=PyObject\u CallObject(myFunction,args);
double getResult=PyFloat\u AsDouble(myResult);
返回0;
}
你读过这篇文章吗:?它似乎回答了你的问题。似乎就是你要找的
PyObject *moduleMainString = PyString_FromString("__main__");
PyObject *moduleMain = PyImport_Import(moduleMainString);

PyRun_SimpleString(
    "def mul(a, b):                                 \n"\
    "   return a * b                                \n"\
);

PyObject *func = PyObject_GetAttrString(moduleMain, "mul");
PyObject *args = PyTuple_Pack(2, PyFloat_FromDouble(3.0), PyFloat_FromDouble(4.0));

PyObject *result = PyObject_CallObject(func, args);

printf("mul(3,4): %.2f\n", PyFloat_AsDouble(result)); // 12
    #include <iostream>
    #include <Python.h>
    using namespace std;
    int main()
    {
    const char *scriptDirectoryName = "/yourDir";
    Py_Initialize();
    PyObject *sysPath = PySys_GetObject("path");
    PyObject *path = PyString_FromString(scriptDirectoryName);
    int result = PyList_Insert(sysPath, 0, path);
    PyObject *pModule = PyImport_ImportModule("mytest");

    PyObject* myFunction = PyObject_GetAttrString(pModule,(char*)"myabs");
    PyObject* args = PyTuple_Pack(1,PyFloat_FromDouble(-2.0));


    PyObject* myResult = PyObject_CallObject(myFunction, args);
    double getResult = PyFloat_AsDouble(myResult);
    return 0;
    }