1. 程式人生 > 程式設計 >使用C++呼叫Python程式碼的方法詳解

使用C++呼叫Python程式碼的方法詳解

一、配置python環境問題

1.首先安裝Python(版本無所謂),安裝的時候選的新增python路徑到環境變數中

安裝之後的資料夾如下所示:

使用C++呼叫Python程式碼的方法詳解

2.在VS中配置環境和庫 右擊專案->屬性->VC++目錄

1)包含目錄:

Python安裝路徑/include

2)庫目錄:

Python安裝路徑/libs

右擊專案->屬性->聯結器->輸入->附加依賴庫

debug下:

python安裝目錄/libs/python37_d.lib

release下:

python安裝目錄/libs/python37.lib

注意

1、debug配置的時候可能沒有python37_d.lib,那就把python37.lib複製一個,然後重新命名為python37_d.lib就可以啦

2、如果一直報錯,但是包含標頭檔案等都沒有問題,那麼你需要看一下你的python是32位還是64位的。然後根據python的環境去配置vs的環境。

二、C++呼叫python函式並輸出返回值

首先可能有個坑!一定要保證這個python函式所在的檔案能夠正常執行!然後把python程式碼放到和C++程式碼同一目錄下。

1、定義Python函式

#!python3
# -*- coding:utf-8 -*-
import base64
import hmac
from hashlib import sha1

def hash_hmac(code,key):
 #sha1加密簽名演算法
 hmac_code = hmac.new(key.encode(),code.encode(),sha1).digest()
 return base64.b64encode(hmac_code).decode()

2、編寫C++程式碼

#include <iostream>
#include<python.h>
using namespace std;
int main()
{
 Py_Initialize();//使用python之前,要呼叫Py_Initialize();這個函式進行初始化
 if (!Py_IsInitialized())
 {
 printf("初始化失敗!");
 return 0;
 }
 PyRun_SimpleString("import sys");
 PyRun_SimpleString("sys.path.append('./')");//這一步很重要,修改Python路徑
 PyObject* pModule = NULL;//宣告變數
 PyObject* pFunc = NULL;// 宣告變數
 pModule = PyImport_ImportModule("hash_hmac");//這裡是要呼叫的檔名hash_hmac.py
 if (pModule == NULL)
 {
 cout << "沒找到" << endl;
 }
 pFunc = PyObject_GetAttrString(pModule,"hash_hmac");//這裡是要呼叫的函式名
 //兩個字串引數
 PyObject* pParams = Py_BuildValue("(ss)","/oss/upload?bucket=test&filekey=test/image/3b/3ba9d94cab2f8868823d71c4445e125a.png\n","q4mJAS777BUbbdVpEqh2XRcZZqNyDweU4GRnM690");
 char* result;
 PyObject* pRet = PyObject_CallObject(pFunc,pParams);//呼叫函式
 int res = 0;
 PyArg_Parse(pRet,"s",&result);//轉換返回型別
 cout << "res:" << result << endl;//輸出結果
 Py_Finalize();//呼叫Py_Finalize,這個根Py_Initialize相對應的。
 return 0;
}

3、解釋部分C++程式碼

PyObject* pParams = Py_BuildValue("(ss)","q4mJAS777BUbbdVpEqh2XRcZZqNyDweU4GRnM690");

在這裡我輸入了兩個字串型別的引數,Py_BuildValue()函式的作用和PyArg_ParseTuple()的作用相反,它將C型別的資料結構轉換成Python物件。

該函式可以和PyArg_ParseTuple()函式一樣識別一系列的格式串,但是輸入引數只能是值,而不能是指標。

它返回一個Python物件和PyArg_ParseTuple()不同的一點是PyArg_ParseTuple()函式它的第一個引數為元組,Py_BuildValue()則不一定會生成一個元組。它生成一個元組僅僅當格式串包含兩個或者多個格式單元,如果格式串為空,返回NONE。

在下面的描述中,括號中的項是格式單元返回的Python物件型別,方括號中的項為傳遞的C的值的型別。

“s” (string) [char *] :將C字串轉換成Python物件,如果C字串為空,返回NONE。

“s#” (string) [char *,int] :將C字串和它的長度轉換成Python物件,如果C字串為空指標,長度忽略,返回NONE。

“z” (string or None) [char *] :作用同”s”。

“z#” (string or None) [char *,int] :作用同”s#”。

“i” (integer) [int] :將一個C型別的int轉換成Python int物件。

“b” (integer) [char] :作用同”i”。

“h” (integer) [short int] :作用同”i”。

“l” (integer) [long int] :將C型別的long轉換成Pyhon中的int物件。

“c” (string of length 1) [char] :將C型別的char轉換成長度為1的Python字串物件。

“d” (float) [double] :將C型別的double轉換成python中的浮點型物件。

“f” (float) [float] :作用同”d”。

“O&” (object) [converter,anything] :將任何資料型別通過轉換函式轉換成Python物件,這些資料作為轉換函式的引數被呼叫並且返回一個新的Python物件,如果發生錯誤返回NULL。

“(items)” (tuple) [matching-items] :將一系列的C值轉換成Python元組。

“[items]” (list) [matching-items] :將一系列的C值轉換成Python列表。

“{items}” (dictionary) [matching-items] :將一系類的C值轉換成Python的字典,每一對連續的C值將轉換成一個鍵值對。

例如:

Py_BuildValue(“”) None

Py_BuildValue(“i”,123) 123

Py_BuildValue(“iii”,123,456,789) (123,789)

Py_BuildValue(“s”,“hello”) ‘hello'

Py_BuildValue(“ss”,“hello”,“world”) (‘hello',‘world')

Py_BuildValue(“s#”,4) ‘hell'

Py_BuildValue(“()”) ()

Py_BuildValue(“(i)”,123) (123,)

Py_BuildValue(“(ii)”,456) (123,456)

Py_BuildValue(“(i,i)”,456)

Py_BuildValue(“[i,i]”,456) [123,456] Py_BuildValue(“{s:i,s:i}”,“abc”,“def”,456) {‘abc': 123,‘def': 456}

Py_BuildValue(“((ii)(ii)) (ii)”,1,2,3,4,5,6) (((1,2),(3,4)),(5,6))

3、執行C++程式

使用C++呼叫Python程式碼的方法詳解

與Python程式碼的預期相同。

使用C++呼叫Python程式碼的方法詳解

三、Python程式碼處理

在釋出軟體的時候,通常我們都不希望程式碼可以直接被別人看到。

以上的Debug目錄中的exe要想能夠單獨執行,必須把python指令碼拷過去。為了不讓別人能直接看到我的程式碼,我拷過去的是生成的.pyc檔案,實現了一個簡單的python程式碼的加密。不過據說可以反編譯,但是對我來說已經夠了。

四、.py和.pyc的區別

原來Python的程式中,是把原始程式程式碼放在.py檔案裡,而Python會在執行.py檔案的時候。將.py形式的程式編譯成中間式檔案(byte-compiled)的.pyc檔案,這麼做的目的就是為了加快下次執行檔案的速度。

所以,在我們執行python檔案的時候,就會自動首先檢視是否具有.pyc檔案,如果有的話,而且.py檔案的修改時間和.pyc的修改時間一樣,就會讀取.pyc檔案,否則,Python就會讀原來的.py檔案。

其實並不是所有的.py檔案在與執行的時候都會產生.pyc檔案,只有在import相應的.py檔案的時候,才會生成相應的.pyc檔案。

五、使用.py生成.pyc

在命令列下使用下列命令即可:

python -m py_compile test.py#單檔案
python -m py_compile /root/src/{file1,file2}.py#多檔案

總結

以上所述是小編給大家介紹的使用C++呼叫Python程式碼的方法詳解,希望對大家有所幫助!