传递元组嵌入式 Python

Posted

技术标签:

【中文标题】传递元组嵌入式 Python【英文标题】:Passing Tuple Embedded Python 【发布时间】:2012-07-12 11:25:42 【问题描述】:

所以我正在编写一个 C++ 应用程序,它使用对 Python 的嵌入式调用来运行一些计算。 我的代码可用于在指定目录中运行任何脚本,以及在 C++ 应用程序和 Python 解释器之间传递和返回一个值。

但是,当我尝试将多个值作为参数传递给 Python 时,我遇到了问题。 以下是我运行 Python 脚本的代码:

double Script::run_script(string moduleName, string funcName, double *params, 
              int numberOfParams)

  PyObject *pName, *pModule, *pDict, *pFunc;
  PyObject *pArgs, *pValue;
  int i;

  // Set aside memory for the path to my scripts to add to sys.path
  char dir[255];
  memset(dir, 0, sizeof(dir));
  /* ********************************************* */
  sprintf(dir, "/home/bmalone/workspace/NumericalAnalysis/Testing"); //Put path into dir
   /* ********************************************* */

  Py_Initialize();

  PyObject *dictModule = PyImport_GetModuleDict();
  PyObject *sys = PyDict_GetItemString(dictModule, "sys");

  // Sys NULL?
  if (sys == NULL)
    
      cerr << "Cannot find sys in dict!" << endl;
      return -1;
    

  dictModule = PyModule_GetDict(sys);
  PyObject *path = PyDict_GetItemString(dictModule, "path");

  PyObject *pPath = PyUnicode_FromString(dir);
  PyList_Append(path, pPath);

  if (pPath);
    //cerr << "PATH > " << PyString_AsString(PyObject_Repr(path)) << endl;
  else
    cerr << "pPath IS NULL" << endl;


  /* Import the module that contains the function/script */
  pModule = PyImport_ImportModule(moduleName.c_str());

  if (pModule);
    //cerr << "pModule ~ " << PyString_AsString(PyObject_Repr(pModule)) << endl;
  else
    cerr << "pModule is NULL!!" << endl;

  //cerr << "Getting dict for argv[1]..." << endl;
  dictModule = PyModule_GetDict(pModule);
  if (dictModule);
    //cerr << "DictModule ~ " << PyString_AsString(PyObject_Repr(dictModule))  << endl;
  else
    cerr << "DictModule is NULL!!" << endl;

  // CALL THE FUNCTION!
  /*
   * argv[1] is the MODULE name, but argv[2] SHOULD BE the function name!
   */
  /* Get a PyObject referencing the function from the module 'pModule' */
  //pFunc = PyObject_GetAttrString(pModule, funcName.c_str());
  pFunc = PyDict_GetItemString(dictModule, funcName.c_str());

  if (pFunc)
    
      PyObject *objRep = PyObject_Repr(pFunc);
      const char* str = PyString_AsString(objRep);
      cerr << "Func is a real boy, too! - " << str  << endl;
    
  else
    cerr << "pFunc is NULL!" << endl;

  /* Setup PyArgs */
  pArgs = PyTuple_New(numberOfParams);
  // Add the data as doubles
  cerr << "<parameters> ~ params size is " << numberOfParams  << endl;
  for (int i = 0; i < numberOfParams; i++)
    
      if (params)
    
      /* **************************** */
      //pValue = PyDouble_AsDouble(params[i]);
      pValue = PyFloat_FromDouble(params[i]);
      /* **************************** */

      cerr << " " << params[i] << endl;
      PyObject* objRep = PyObject_Repr(pValue);
      const char* strRep = PyString_AsString(objRep);
      cerr << ">> pValue = " << strRep << endl;
      PyTuple_SetItem(pArgs, i, pValue);
    
      else
    break;
    

  cerr << "<Module> - " << moduleName << ", is null: " << (pModule == NULL) << endl;
  cerr << "<Function> - " << funcName << ", is null: " << (pFunc == NULL) << endl;

  // Get the retun value
  cerr << "<Calling Function>" << endl;
  //pValue = PyObject_CallFunction(pFunc, "f", 15.0); // **WORKS**
  pValue = PyObject_CallObject(pFunc, pArgs); // **WORKS**

  //pValue = PyObject_CallObject(pFunc, NULL);
  //pValue = PyEval_CallObject(pFunc, NULL);
  //pValue = PyObject_CallFunction(pFunc, NULL);
  //pValue = PyObject_CallObject(pFunc, args);

  //pValue = PyEval_CallObject(pFunc, args);

  //cerr << "ANSWER ---> " << PyFloat_AsDouble(pValue) << endl;

  return PyFloat_AsDouble(pValue);
  Py_Finalize();

编辑: 在我原来的帖子中,我做了一个我忘记做的更改,这是一个阻止任何脚本运行的错误。上面的代码正确地运行任何脚本,except 只有当 pArgs 有 --1-- 元素时它才有效。每当我尝试传递多个元素时,即使是为了打印出同一个脚本,脚本甚至都不会运行。 但如果它只是 1,那么它就完美了。

我似乎无法弄清楚将超过 1 个参数传递给我的脚本我做错了什么。 这是我试图从 C++ 运行的脚本(适用于 1 个参数的脚本):

#!/usr/bin/python
'''
Created on Jul 12, 2012

@author: bmalone
'''
import sys


def doubleTwo(x, y):
    print str(sys.argv)
    print "Can haz doubling?\n"


if __name__ == '__main__':
    doubleTwo()

任何帮助将不胜感激!

【问题讨论】:

对不起,如果我忽略了任何内容,但您是否包含了调用 Script::run_script() 的 C++ 代码?该错误可能与您如何构造作为 params 传递的双精度数组有关。 【参考方案1】:

我发现了我遇到的问题。 在我的函数中,我试图访问命令行参数,而在编写我的函数时,我指定它们正在被传递参数——我没有这样做。

将来,对于任何发现嵌入式 Python 有问题的人,我发现 Python-C API 中有一个非常有用的错误部分,如果 PyErr_Occurred() 为 true,PyErr_Print() 会将错误打印到 stderr。

我要么需要修复传递的实际参数,要么(我最终使用的)是在使用“PyObject_CallObject”调用函数之前使用“PySys_SetArgv”,并通过在 sys.argv 上建立索引来访问我在 Python 中需要的参数。

【讨论】:

以上是关于传递元组嵌入式 Python的主要内容,如果未能解决你的问题,请参考以下文章

在 C++ 中嵌入 Python。传递接收列表列表的字符串向量

七:python 对象类型详解五:元组

keras。初始化双向LSTM。传递单词嵌入

数据库系统概念:基础的SQL

将信息从 UINavigationController 传递到嵌入式 UIViewController

嵌入 Python 时共享数组的最简单方法