1. 程式人生 > >C呼叫Python的示例程式碼

C呼叫Python的示例程式碼

fext_tensorrt的程式碼如下:

def fext_call(arg1, arg2):
    print("fext_call()", arg1, arg2)
    return "fext_call"

C的程式碼如下,傳遞兩個引數,獲取並輸出函式呼叫結果:

#include <Python.h>

int python_test()
{
    //初始化,載入python的擴充套件模組
    Py_Initialize();
    //判斷初始化是否成功
    if(!Py_IsInitialized())
    {
        printf("Python init failed!\n");
        return -1;
    }

    //匯入當前路徑
    PyRun_SimpleString("import sys");
    PyRun_SimpleString("sys.path.append('./')");

    //對齊
    PyObject *pName   = NULL;
    PyObject *pModule = NULL;
    PyObject *pDict   = NULL;
    PyObject *pFunc   = NULL;
    PyObject *pArgs   = NULL;

    //載入名為py_add的python指令碼
    pName = PyString_FromString("fext_tensorrt");
    pModule = PyImport_Import(pName);
    if (!pModule)
    {
        GH_LOG_INFO("Load py_add.py failed!");
        getchar();
        return -1;
    }
    
    pDict = PyModule_GetDict(pModule);
    if (!pDict)
    {
        GH_LOG_INFO("Can't find dict in py_add!");
        return -1;
    }
        
    pFunc = PyDict_GetItemString(pDict, "fext_call");
    if (!pFunc || !PyCallable_Check(pFunc))
    {
        GH_LOG_INFO("Can't find function!");
        return -1;
    }

    /*
    用到PyTuple_New,Py_BuildValue,PyTuple_SetItem等幾個函式
    */
    pArgs = PyTuple_New(2);
    
    //  PyObject* Py_BuildValue(char *format, ...) 
    //  把C++的變數轉換成一個Python物件。當需要從 
    //  C++傳遞變數到Python時,就會使用這個函式。此函式 
    //  有點類似C的printf,但格式不同。常用的格式有 
    //  s 表示字串, 
    //  i 表示整型變數, 如Py_BuildValue("ii",123,456)
    //  f 表示浮點數, 
    //  O 表示一個Python物件

    PyTuple_SetItem(pArgs, 0, Py_BuildValue("i",  123 ));
    PyTuple_SetItem(pArgs, 1, Py_BuildValue("s", "789"));

    //呼叫python的add函式
    PyObject* pResult = PyObject_CallObject(pFunc,pArgs);
    GH_LOG_INFO("result=%s", PyString_AsString(pResult));

    //清理python物件
    if (pName)
    {
        Py_DECREF(pName);
    }
    if (pArgs)
    {
        Py_DECREF(pArgs);
    }
    if (pModule)
    {
        Py_DECREF(pModule);
    }
    
    //關閉python呼叫
    Py_Finalize();

    return 0;
    
}