从C调用python hello world函数,解析字符串参数

我使用此答案中的代码创建以下文件

callpython.c

#include  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 */ //fprintf(stderr,"pName is %s\n", pName); PyRun_SimpleString("import sys"); PyRun_SimpleString("sys.path.append(\".\")"); //PySys_SetArgv(argc, argv); 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 argument\n"); return 1; } /* iValue reference stolen here: */ PyTuple_SetItem(pArgs, i, pValue); //PyTuple_SetItem(pArgs, i, argv[i + 3]); } pValue = PyObject_CallObject(pFunc, pArgs); Py_DECREF(pArgs); if (pValue != NULL) { printf("Result of call: %ld\n", PyInt_AsLong(pValue)); Py_DECREF(pValue); } else { Py_DECREF(pFunc); Py_DECREF(pModule); PyErr_Print(); fprintf(stderr,"Call failed\n"); 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; } 

我在与helloWorld.py相同的目录中创建了另一个文件。 这个python脚本的内容是

 def helloworldFunc(a): print 'Hello '+str(a) 

我编译并运行callpython.c,如下所示

  g++ -o callpython callpython.c -lpython2.7 -lm -L/usr/lib/python2.7/config && ./callpython helloworld helloworldFunc world 

而不是打印“Hello world”,它打印“Hello 0”

为什么它不将python函数参数解析为字符串?

示例代码将参数解析为整数,购买时您已经传递了一个字符串。 atoi("world")返回0,所以这是你得到的整数:

 /* Create tuple of the correct length for the arguments. */ pArgs = PyTuple_New(argc - 3); for (i = 0; i < argc - 3; ++i) { /* Convert each C argv to a C integer, then to a Python integer. */ pValue = PyInt_FromLong(atoi(argv[i + 3])); if (!pValue) { Py_DECREF(pArgs); Py_DECREF(pModule); fprintf(stderr, "Cannot convert argument\n"); return 1; } /* iValue reference stolen here: */ /* Store the Python integer in the tuple at the correct offset (i) */ PyTuple_SetItem(pArgs, i, pValue); } 

将转换行更改为以下内容以处理任何字符串:

 pValue = PyString_FromString(argv[i + 3]); 

解决了这个问题。 罪魁祸首是这条线

 pValue = PyInt_FromLong(atoi(argv[i + 3])); 

它将python脚本的每个参数解析为整数。

当替换为以下行时,它将每个参数解析为字符串

 pValue = PyString_FromString(argv[i+3]); 

我还没有真正理解pValue是如何工作的,但这解决了现在的问题。