當前位置:成語大全網 - 新華字典 - 求助 關於c程序中嵌入Python的問題

求助 關於c程序中嵌入Python的問題

在C/C++中嵌入Python也比較簡單,首先需要在VC中添加Python的include文件目錄和lib文件目錄:

VC6.0下,打開 tools->options->directories->show directories for,將Python安裝目錄下的inlude目錄添加到inlude files項中,將libs目錄添加到library files項中。

VC2005下,打開tools->options->項目和解決方案->VC++目錄,然後做相同工作。

代碼如下:

//在debug下執行出錯,“無法找到python31_d.lib文件”,後查到原因是:在debug下生成必須要有python31_d.lib文件,否則只能在release下生成

#include <python.h>

int main()

{

Py_Initialize();

PyRun_SimpleString("Print 'hi, python!'");

Py_Finalize();

return 0;

}

Py_Initialize函數原型是:void Py_Initialize(),在嵌入Python腳本時必須使用該函數,它初始化Python解釋器,在使用其他的Python/C API之前必須先調用該函數。可以使用Py_IsInitialized函數判斷是否初始化成功,成功返回True。

PyRun_SimpleString函數原型是int PyRun_SimpleString(const char *command),用來執行壹段Python代碼。註意:是否需要維持語句間的縮進呢?

Py_Finalize函數原型是void Py_Finalize(),用於關閉Python解釋器,釋放解釋器所占用的資源。

PyRun_SimpleFile函數可以用來運行".py"腳本文件,函數原型如下:

int PyRun_SimpleFile(FILE *fp, const char *filename);

其 中fp是打開的文件指針,filename是要運行的python腳本文件名。但是由於該函數官方發布的是由visual studio 2003.NET編譯的,如果使用其他版本的編譯器,FILE定義可能由於版本原因導致崩潰。同時,為簡便起見可以使用如下方式來代替該函數:

PyRun_SimpleString("execfile(‘file.py’)"); //使用execfile來運行python文件

Py_BuildValue()用於對數字和字符串進行轉換處理,變成Python中相應的數據類型(在C語言中,所有Python類型都被聲明為PyObject類型),函數原型如下:

PyObject *Py_BuildValue(const char *format, …..);

PyString_String()用於將PyObject*類型的變量轉換成C語言可以處理的char*型,具體原型如下:

char* PyString_String(PyObject *p);

列表操作函數:

PyObject * PyList_New(Py_ssize_t len);

int PyList_SetItem(PyObject *list, Py_ssize_t index, PyObject *item);

PyObject * PyList_GetItem(PyObject *list, Py_ssize_t index);

int PyList_Append(PyObject *list, PyObject *item);

int PyList_Sort(PyObject *list);

int PyList_Reverse(PyObject *list);

Py_ssize_t PyList_Size(PyObject *list);

元組操作函數:

int PyTuple_New(Py_ssize_t len);

int PyTuple_SetItem(PyObject *p, Py_ssize_t pos, PyObject *o);

PyObject * PyTuple_GetItem(PyObject *p, Py_ssize_t pos);

int _PyTuple_Resize(PyObject **p, Py_ssize_t newsize); //註意是**指針

字典操作函數:

PyObject * PyDict_New();

int PyDict_SetItem(PyObject *p, PyObject *key, PyObject *val);

int PyDict_SetItemString(PyObject *p, const char *key, PyObject *val);

PyObject* PyDict_GetItem(PyObject *p, PyObject *key);

PyObject* PyDict_GetItemString(PyObject *p, const char *key);

//與PyDict_SetItemString對應

int PyDict_DelItem(PyObject *p, PyObject *key);

int PyDict_DelItemString(PyObject *p, char *key);

//與PyDict_SetItemString對應

int PyDict_Next(PyObject *p, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue);

PyObject* PyDict_Items(PyObject *p);

PyObject* PyDict_keys(PyObject *p);

PyObject* PyDict_Values(PyObject *p);

在C/C++中使用Python對象應正確地處理引用計數問題,否則容易導致內存泄漏。當使用Python/C API中的函數創建列表、元組、字典等後,在對其完成操作後應該使用Py_CLEAR()和Py_DECREF()等宏來銷毀這些對象。原型如下:

void Py_CLEAR(PyObject *o);

void Py_DECREF(PyObject *o);

其中,對於Py_CLEAR函數,參數可以為NULL指針,表示不進行任何操作,但是Py_DECREF函數不能為NULL指針,否則導致錯誤。

使用PyImport_Import()函數可以在C中導入Python模塊,返回壹個模塊對象。函數原型為:

PyObject* PyImport_Import(PyObject *name);

PyModule_GetDict()函數可以獲得Python模塊中的函數列表,返回壹個字典,字典中的關鍵字為函數名,值為函數的調用地址。原型如下:

PyObject* PyModule_GetDict(PyObject *module);

使用PyObject_CallObject()函數和PyObject_CallFunction()函數可以在C中調用Python中的函數,原型如下:

PyObject* PyObject_CallObject(PyObject *callable_object, PyObject *args);

//args是元組形式

PyObject* PyObject_CallFunction(PyObject *callable, char *format, ……);

//format是類似”iss”這樣的參數類型,後面是指定參數

可以使用PyCallable_Check(func)來判斷是否可以調用函數,可以則返回True。