2012-07-12 67 views
0

所以我正在編寫一個C++應用程序,它使用嵌入式調用來運行一些計算。 我有代碼工作在指定目錄中運行任何腳本,以及在C++應用程序和Python解釋器之間傳遞和返回一個值。傳遞元組嵌入式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(); 
} 

編輯: 在我原來的職位,我做了一個改變我忘了我做了,這是防止任何腳本運行錯誤。上述代碼正確運行任何腳本,,但只有在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() 

任何幫助,將不勝感激!

+0

對不起,如果我忽略了任何東西,但是您是否包含調用'Script :: run_script()'的C++代碼?這個錯誤可能與你如何構造你以'params'傳遞的雙精度數組有關。 – jogojapan 2012-07-13 03:22:35

回答

0

我想出了我遇到的問題。 在我的函數中,我試圖訪問命令行參數,而在編寫我的函數時,我指定他們正在傳遞參數 - 我沒有這樣做。如果PyErr_Occurred()爲true,PyErr_Print()會將錯誤打印到stderr中,但是對於任何發現嵌入式Python有問題的人來說,我發現Python-C API中有一個極其有用的錯誤部分。 。

我需要修復傳遞的實際參數,或者(我最終要做的)在我用「PyObject_CallObject」調用函數之前使用「PySys_SetArgv」,並通過sys.argv上的索引訪問我需要的參數。