一、如何embedding python,Python文檔中有專門一章闡述https://docs.python.org/3.5/extending/embedding.htm;html
一、庫文件:在vs--c/c++--附加包含文件中添加目;連接中也要添加,:將python中的include,libs二個目錄添加進來python
二、對於Python,沒有調試庫,可直接將運行庫複製一份,名稱後面加上_d,就可用,可不能源代碼調試而已,同時修改c++
pyconfig.hapi
#ifdef _DEBUG
//# define Py_DEBUG //將這行註釋掉
#endif app
和object.h函數
#if defined(Py_DEBUG) && !defined(Py_TRACE_REFS)
// #define Py_TRACE_REFS //將這行註釋掉
#endifui
三、因爲QT中定義了slots做爲關鍵了,而python3中有使用slot做爲變量,因此有衝突,辦法是:spa
A、在vs中-屬性-c/c++ -預處理器-預處理器定義-中添加:QT_NO_KEYWORDS指令,調試
在Dt的項目文件中.pro文件中添加 config +=_no_keywords指令,再生成vs的項目文件,也就自動添加了上面的指令orm
這種方法是全局的,同時也取消 forever,foreach的宏定義,由於不少代碼使用foreach,因此反作用大;
B、在使用第三方代碼時暫時取消衝突的宏定義,而後從新定義相關宏,如QT調用第三方python時,只是在python的object.h中 slots衝突,所以修改object.h:
typedef struct{
const char* name;
int basicsize;
int itemsize;
unsigned int flags;
#undef slots //這裏取消slots宏定義
PyType_Slot *slots; /* terminated by slot==0. */
#define slots Q_SLOTS //這裏恢復slots宏定義與QT中QObjectDefs.h中一致
} PyType_Spec;
四、在主程序中執行一開始Py_Initialize(); 時就出現錯誤
解決辦法是:Py_SetPythonHome((wchar_t*)(L"C:\\Python3"));
是由於我安裝python的時候沒有添加PYTHONHOME這個環境變量
在Py_Initialize()以前調用下Py_SetPythonHome("C:\\Python3");就能夠了
五、用於導入sys模塊,以供程序使用,這是基本模塊
PyRun_SimpleString("import sys");
六、在執行pModule = PyImport_ImportModule("jptest"); 語句導入自定義模塊時,返回對pModule爲NULL,是因爲自定義模塊的位置不在python系統搜索的系統目錄列表內,所以解決辦法是在系統搜索目錄列表中添加目錄:
PyRun_SimpleString("sys.path.append('D:\\develop\\qtpythontest\\Win32\\Debug')");
注意字符中中"\"必須前面加上「\\",也就是單個"\"是轉意符;並且目錄尾部不能添加多餘的\符;若是不能確承認將它們顯示出來用下面這個語句:PyRun_SimpleString("print(sys.path)");
七、數據轉換,在c/c++與python交互時,都是經過PyObject來傳入和傳出數據的,Python提供相關函數對PyObject數據進行轉換,轉換時使用格式字符串來控制生成的對象類型,具體可參見https://docs.python.org/3.5/c-api/arg.html官方文檔:
A) 將c/c++數據轉換成PyObject:
PyObject *pInt=Py_BuildValue("i",2003);
PyObject *pStr=Py_BuildValue("s","This is a string");
PyObject *pTuples=Py_BuildValue("()"); //生成空元組,可做爲調用不包含任何參數的函數時,傳遞空參數
PyObject *pTuples=Py_BuildValue("(s)","This is a string"); //生成一個元素的元組,可做爲調用只包含一個字符參數的函數時,傳遞一個字符參數
B) 將PyObject數據轉換成c/c++數據:
1) int bb=0; PyArg_Parse(pObjcet,"i",&bb); //這裏pObject是包含整數數據的Python對象,第二個字符串參數"i"指定轉換類型,第三個參數將結果值存入bb變量;
2) char * cc=NULL; PyArg_parse(pObject,"s",&cc); //這是字符串轉換
3) char * cc=NULL; PyArg_parse(pObject,"(s)",&cc); //這是包含一個字符串元素元組轉換
八、調用Python模塊函數時,傳入參數時,要構造一個參數元組,如:presult = PyObject_CallObject(pfunction, args);這裏args就是一個元組,做爲被調用函數的參數列表;
A、如參數爲空,則這樣構造:args=Py_BuildValues("(si)","abc",10); 表示構造二個參數的元組,一個是字符型,另外一個是整;多個參數,可參照處;
B、若是參數爲空,則需構造一個包含0個元素元組:args=Py_BuildValues("()");
注意以上二種都在格式字符串中包含"()",這是指示構造元;做爲函數調用參數必須傳遞元組,也必須這樣構;
下例是經過可變參數來構造調用函數參數元組:
int PythonHandler::PyModuleRunFunction(const char *module, const char *function,
const char *result_format, void *result, const char *args_format, ...) {
......
//這裏構造調用函數所使用的參數元組
va_list args_list; va_start(args_list, args_format); args = Py_VaBuildValue(const_cast<char *>(args_format), args_list); va_end(args_list);
...
if (!args)
{
//args爲空,則元組構造失敗
Py_DECREF(pfunction);
return -3;
}
...
presult = PyObject_CallObject(pfunction,args); //調用函數