Python與C++互動程式設計

DW_Deven發表於2015-11-17

C++嵌入Python

  • 實現原理
    這裡寫圖片描述

  • SKILL
    能夠實現在C++中嵌入對Python函式的呼叫、物件的建立、類的呼叫;

  • 程式碼

#include <iostream>
#include "Python.h"
using namespace std;

int main(int argc, char *argv[])
{
    int j;
    int  i = 12;
    Py_Initialize();
    if (!Py_IsInitialized())
    {
        cout << "not INit" << endl;
        getchar();
        return -1;
    }
    PyObject *pModule = NULL;
    PyObject *pFunc = NULL;
    PyObject *pNum = NULL;
    PyObject *pGet = NULL;
    PyObject *pStu = NULL;
    PyObject *pInstan = NULL;
    PyDict_New();
    PyRun_SimpleString("import sys");
    PyRun_SimpleString("sys.path.append('./')");
    pModule = PyImport_ImportModule("hello");
    if (!pModule)
    {
        cout << "not module" << endl;
        getchar();
        return -1;
    }
    pFunc = PyObject_GetAttrString(pModule, "hi");
    if (!pFunc)
    {
        cout << "not func" << endl;
        getchar();
        return -1;
    }

    //pGet = PyInt_FromLong(i);
    pGet = Py_BuildValue("(i)",i);
    //pGet = PyTuple_New(1); //
    //PyTuple_SetItem(pGet, 0, PyInt_FromLong(i));
    //
    //pNum = PyObject_CallFunction(pFunc, "i",1);
    pNum = PyObject_CallObject(pFunc, pGet);
    //pNum = PyEval_CallObject(pFunc, pGet);
    //
    j = PyInt_AsLong(pNum);
    cout << j << endl;
    Py_DECREF(pFunc);
    pFunc = PyObject_GetAttrString(pModule, "Student");
    if (!pFunc)
    {
        cout << "not func" << endl;
        getchar();
        return -1;
    }
    pStu = PyInstance_New(pFunc, NULL, NULL);
    if (!pStu)
    {
        cout << "notstu" << endl;
        getchar();
        return -1;
    }
    PyObject_CallMethod(pStu, "SetNam","s","lilei");
    PyObject_CallMethod(pStu, "print_name",NULL,NULL);
    getchar();
    Py_Finalize();
    return 0;
}
  • 遇到並解決的問題

    1. 編譯時需要VS工具選項中除錯-符號的符號自動載入來為編譯檔案自動載入符號;
    2. 專案的預編標頭檔案需要加上WIN;
    3. 需要把py檔案放到exe生成檔案的同級目錄下才能進行查詢
  • 未解決的問題

    1. pGet = PyInt_FromLong(i)用這樣的方式建立一個PyObject變數無法建立並導致後面的函式執行全部出錯;
    2. 如果要獲取Py檔案中已經賦值了的物件,是否只能通過py檔案中的函式才能獲取得到?

C++擴充套件Python

  • 實現原理
    這裡寫圖片描述

  • SKILL
    能夠實現在將C++的函式封裝,轉化成可被Python呼叫的模板、Python C API的函式應用;

  • 程式碼

#include <iostream>
#include "Python.h"
using namespace std;

int numchan(int a)
{
    return a + 1;
}

static PyObject * _numchan(PyObject *self, PyObject *argc)
{
    int a;
    int re;
    PyArg_ParseTuple(argc, "i", &a);
    re = numchan(a);
    cout << re << endl;
    return PyInt_FromLong(re);
}

static PyMethodDef numchanModuleMethods[] = {
    {
        "numchan",
        _numchan,
        METH_VARARGS,
        ""
    },
    {NULL,NULL,0,NULL}
};

PyMODINIT_FUNC initnumchan(void)
{
    Py_InitModule("numchan", numchanModuleMethods);
}
  • 遇到並解決的問題

    1. 函式初始化入口的名稱必須和之前的封裝函式的名稱完全一致;
    2. 生成pyd檔案的時候需要通過VS命令列編譯生成;
    3. 封裝的函式和該函式返回的物件必須都是PyObject;
  • 未解決的問題
    如果不使用生成pyd或者dll檔案的方式進行擴充套件Python的話,那麼擴充套件的具體實現是怎麼樣的?把C++轉化成Python可呼叫的物件是什麼物件?PyObject??然後Python呼叫的時候通過函式直接去呼叫嗎?還是通過Import?
    猜測是否是下圖模式
    這裡寫圖片描述

相關文章