1.首先安裝Python(版本無所謂),安裝的時(shí)候選的添加python路徑到環(huán)境變量中
廣陵ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場景,ssl證書未來市場廣闊!成為創(chuàng)新互聯(lián)公司的ssl證書銷售渠道,可以享受市場價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:18980820575(備注:SSL證書合作)期待與您的合作!
安裝之后的文件夾如下所示:
2.在VS中配置環(huán)境和庫 右擊項(xiàng)目->屬性->VC++目錄
1)包含目錄:
Python安裝路徑/include
2)庫目錄:
Python安裝路徑/libs
右擊項(xiàng)目->屬性->連接器->輸入->附加依賴庫
debug下:
python安裝目錄/libs/python37_d.lib
release下:
python安裝目錄/libs/python37.lib
注意
1、debug配置的時(shí)候可能沒有python37_d.lib,那就把python37.lib復(fù)制一個(gè),然后重命名為python37_d.lib就可以啦
2、如果一直報(bào)錯(cuò),但是包含頭文件等都沒有問題,那么你需要看一下你的python是32位還是64位的。然后根據(jù)python的環(huán)境去配置vs的環(huán)境。
首先可能有個(gè)坑!一定要保證這個(gè)python函數(shù)所在的文件能夠正常運(yùn)行!然后把python代碼放到和C++代碼同一目錄下。
1、定義Python函數(shù)
#!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#include using namespace std; int main() { Py_Initialize();//使用python之前,要調(diào)用Py_Initialize();這個(gè)函數(shù)進(jìn)行初始化 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");//這里是要調(diào)用的文件名hash_hmac.py if (pModule == NULL) { cout << "沒找到" << endl; } pFunc = PyObject_GetAttrString(pModule, "hash_hmac");//這里是要調(diào)用的函數(shù)名 //兩個(gè)字符串參數(shù) PyObject* pParams = Py_BuildValue("(ss)", "/oss/upload?bucket=test&filekey=test/image/3b/3ba9d94cab2f8868823d71c4445e125a.png\n" , "q4mJAS777BUbbdVpEqh3XRcZZqNyDweU4GRnM690"); char* result; PyObject* pRet = PyObject_CallObject(pFunc, pParams);//調(diào)用函數(shù) int res = 0; PyArg_Parse(pRet, "s", &result);//轉(zhuǎn)換返回類型 cout << "res:" << result << endl;//輸出結(jié)果 Py_Finalize();//調(diào)用Py_Finalize,這個(gè)根Py_Initialize相對應(yīng)的。 return 0; }
3、解釋部分C++代碼
PyObject* pParams = Py_BuildValue("(ss)", "/oss/upload?bucket=test&filekey=test/image/3b/3ba9d94cab2f8868823d71c4445e125a.png\n" , "q4mJAS777BUbbdVpEqh3XRcZZqNyDweU4GRnM690");
在這里我輸入了兩個(gè)字符串類型的參數(shù),Py_BuildValue()函數(shù)的作用和PyArg_ParseTuple()的作用相反,它將C類型的數(shù)據(jù)結(jié)構(gòu)轉(zhuǎn)換成Python對象。
該函數(shù)可以和PyArg_ParseTuple()函數(shù)一樣識(shí)別一系列的格式串,但是輸入?yún)?shù)只能是值,而不能是指針。
它返回一個(gè)Python對象和PyArg_ParseTuple()不同的一點(diǎn)是PyArg_ParseTuple()函數(shù)它的第一個(gè)參數(shù)為元組,Py_BuildValue()則不一定會(huì)生成一個(gè)元組。它生成一個(gè)元組僅僅當(dāng)格式串包含兩個(gè)或者多個(gè)格式單元,如果格式串為空,返回NONE。
在下面的描述中,括號(hào)中的項(xiàng)是格式單元返回的Python對象類型,方括號(hào)中的項(xiàng)為傳遞的C的值的類型。
“s” (string) [char *] :將C字符串轉(zhuǎn)換成Python對象,如果C字符串為空,返回NONE。
“s#” (string) [char *, int] :將C字符串和它的長度轉(zhuǎn)換成Python對象,如果C字符串為空指針,長度忽略,返回NONE。
“z” (string or None) [char *] :作用同”s”。
“z#” (string or None) [char *, int] :作用同”s#”。
“i” (integer) [int] :將一個(gè)C類型的int轉(zhuǎn)換成Python int對象。
“b” (integer) [char] :作用同”i”。
“h” (integer) [short int] :作用同”i”。
“l(fā)” (integer) [long int] :將C類型的long轉(zhuǎn)換成Pyhon中的int對象。
“c” (string of length 1) [char] :將C類型的char轉(zhuǎn)換成長度為1的Python字符串對象。
“d” (float) [double] :將C類型的double轉(zhuǎn)換成python中的浮點(diǎn)型對象。
“f” (float) [float] :作用同”d”。
“O&” (object) [converter, anything] :將任何數(shù)據(jù)類型通過轉(zhuǎn)換函數(shù)轉(zhuǎn)換成Python對象,這些數(shù)據(jù)作為轉(zhuǎn)換函數(shù)的參數(shù)被調(diào)用并且返回一個(gè)新的Python對象,如果發(fā)生錯(cuò)誤返回NULL。
“(items)” (tuple) [matching-items] :將一系列的C值轉(zhuǎn)換成Python元組。
“[items]” (list) [matching-items] :將一系列的C值轉(zhuǎn)換成Python列表。
“{items}” (dictionary) [matching-items] :將一系類的C值轉(zhuǎn)換成Python的字典,每一對連續(xù)的C值將轉(zhuǎn)換成一個(gè)鍵值對。
例如:
Py_BuildValue(“”) None
Py_BuildValue(“i”, 123) 123
Py_BuildValue(“iii”, 123, 456, 789) (123, 456, 789)
Py_BuildValue(“s”, “hello”) ‘hello'
Py_BuildValue(“ss”, “hello”, “world”) (‘hello', ‘world')
Py_BuildValue(“s#”, “hello”, 4) ‘hell'
Py_BuildValue(“()”) ()
Py_BuildValue(“(i)”, 123) (123,)
Py_BuildValue(“(ii)”, 123, 456) (123, 456)
Py_BuildValue(“(i,i)”, 123, 456) (123, 456)
Py_BuildValue(“[i,i]”, 123, 456) [123, 456] Py_BuildValue(“{s:i,s:i}”, “abc”, 123, “def”, 456) {‘a(chǎn)bc': 123, ‘def': 456}
Py_BuildValue(“((ii)(ii)) (ii)”, 1, 2, 3, 4, 5, 6) (((1, 2), (3, 4)), (5, 6))
3、運(yùn)行C++程序
與Python代碼的預(yù)期相同。
在發(fā)布軟件的時(shí)候,通常我們都不希望代碼可以直接被別人看到。
以上的Debug目錄中的exe要想能夠單獨(dú)運(yùn)行,必須把python腳本拷過去。為了不讓別人能直接看到我的代碼,我拷過去的是生成的.pyc文件,實(shí)現(xiàn)了一個(gè)簡單的python代碼的加密。不過據(jù)說可以反編譯,但是對我來說已經(jīng)夠了。
原來Python的程序中,是把原始程序代碼放在.py文件里,而Python會(huì)在執(zhí)行.py文件的時(shí)候。將.py形式的程序編譯成中間式文件(byte-compiled)的.pyc文件,這么做的目的就是為了加快下次執(zhí)行文件的速度。
所以,在我們運(yùn)行python文件的時(shí)候,就會(huì)自動(dòng)首先查看是否具有.pyc文件,如果有的話,而且.py文件的修改時(shí)間和.pyc的修改時(shí)間一樣,就會(huì)讀取.pyc文件,否則,Python就會(huì)讀原來的.py文件。
其實(shí)并不是所有的.py文件在與運(yùn)行的時(shí)候都會(huì)產(chǎn)生.pyc文件,只有在import相應(yīng)的.py文件的時(shí)候,才會(huì)生成相應(yīng)的.pyc文件。
在命令行下使用下列命令即可:
python -m py_compile test.py#單文件 python -m py_compile /root/src/{file1,file2}.py#多文件
總結(jié)
以上所述是小編給大家介紹的使用C++調(diào)用Python代碼的方法詳解,希望對大家有所幫助!