C++通過 Py_Initialize實現(xiàn)對Python的嵌入調(diào)用
在現(xiàn)代軟件開發(fā)中,性能(C++)與靈活性(Python)的結(jié)合是許多大型項目的首選方案。無論是游戲引擎(如 Unreal Engine)還是高性能計算工具,通過在 C++ 中嵌入 Python 腳本,可以讓用戶在不重新編譯程序的情況下編寫插件或邏輯。
本文將帶你走進(jìn) Python C API 的世界,重點介紹如何通過 Py_Initialize 實現(xiàn) C++ 對 Python 的嵌入調(diào)用。
為什么要嵌入 Python
- 腳本化:允許用戶自定義邏輯。
- 快速原型:利用 Python 豐富的庫(如 NumPy, SciPy)處理數(shù)據(jù),而核心邏輯保持在 C++ 中。
- 邏輯分離:將頻繁變動的業(yè)務(wù)邏輯放在腳本層,核心底層放在 C++ 層。
核心流程圖
在深入代碼之前,我們先看下 C++ 調(diào)用 Python 的標(biāo)準(zhǔn)生命周期:
第一步:環(huán)境配置
要在 C++ 中使用 Python API,你需要:
頭文件:Python.h(位于 Python 安裝目錄的 include 文件夾)。
庫文件:python3x.lib(Windows)或 libpython3x.so(Linux)。
注意:確保你的 C++ 編譯位數(shù)(x64/x86)與 Python 安裝版本一致,否則會報鏈接錯誤。
第二步:最簡實現(xiàn):Hello World
我們先從最簡單的初始化和運行一段 Python 代碼開始。
#include <Python.h>
#include <iostream>
int main() {
// 1. 初始化 Python 解釋器
Py_Initialize();
if (!Py_IsInitialized()) {
std::cerr << "Python 初始化失?。? << std::endl;
return -1;
}
// 2. 執(zhí)行簡單的 Python 語句
PyRun_SimpleString("print('Hello from Python! I am embedded in C++.')");
PyRun_SimpleString("import platform; print('Python Version:', platform.python_version())");
// 3. 釋放資源
Py_Finalize();
return 0;
}第三步:進(jìn)階——調(diào)用 Python 函數(shù)并傳遞參數(shù)
在實際項目中,我們通常需要加載一個 .py 文件,并調(diào)用其中的特定函數(shù)。
1. 準(zhǔn)備 Python 腳本 (script.py)
# script.py
def add(a, b):
print(f"Python 收到參數(shù): {a} 和 ")
return a + b2. C++ 調(diào)用代碼
調(diào)用過程涉及 Python 對象的引用計數(shù)管理,這是最容易出錯的地方。
#include <Python.h>
#include <iostream>
int main() {
Py_Initialize();
// 將當(dāng)前路徑加入 Python 的搜索路徑,否則找不到 script.py
PyRun_SimpleString("import sys; sys.path.append('.')");
// 加載模塊
PyObject* pModule = PyImport_ImportModule("script");
if (pModule) {
// 獲取函數(shù)對象
PyObject* pFunc = PyObject_GetAttrString(pModule, "add");
if (pFunc && PyCallable_Check(pFunc)) {
// 創(chuàng)建參數(shù)元組 (3, 5)
PyObject* pArgs = PyTuple_Pack(2, PyLong_FromLong(3), PyLong_FromLong(5));
// 調(diào)用函數(shù)
PyObject* pValue = PyObject_CallObject(pFunc, pArgs);
if (pValue) {
std::cout << "C++ 收到結(jié)果: " << PyLong_AsLong(pValue) << std::endl;
Py_DECREF(pValue);
}
Py_DECREF(pArgs);
}
Py_XDECREF(pFunc);
Py_DECREF(pModule);
} else {
PyErr_Print(); // 打印 Python 錯誤堆棧
}
Py_Finalize();
return 0;
}核心 API 詳解
| 函數(shù) | 功能 |
| Py_Initialize() | 啟動 Python 解釋器并加載基本模塊。 |
| PyRun_SimpleString() | 執(zhí)行單行 Python 代碼,簡單快捷,但無法獲取返回值。 |
| PyImport_ImportModule() | 動態(tài)加載一個 .py 模塊。 |
| PyObject_GetAttrString() | 從模塊中獲取屬性(如函數(shù)、類)。 |
| PyTuple_Pack() | 將 C++ 數(shù)據(jù)打包成 Python 的元組,用于函數(shù)傳參。 |
| Py_DECREF() | 減少引用計數(shù)。極其重要,否則會導(dǎo)致嚴(yán)重的內(nèi)存泄漏。 |
避坑指南(經(jīng)驗總結(jié))
- 路徑問題:Python 解釋器默認(rèn)不搜索 C++ 可執(zhí)行文件目錄。務(wù)必使用
sys.path.append('.')或設(shè)置PYTHONPATH環(huán)境變量。 - Debug/Release 陷阱:在 Windows 上,如果你編譯 C++ 為 Debug 模式,它會嘗試尋找
python3x_d.lib。如果你的 Python 環(huán)境沒有安裝調(diào)試庫,請確保 C++ 使用 Release 模式,或者手動修改宏定義。 - 引用計數(shù):遵循“誰創(chuàng)建,誰負(fù)責(zé)”的原則。如果你通過
PyImport或PyObject_Get獲得了對象,不用時必須Py_DECREF。 - 多線程 (GIL):如果你的 C++ 程序是多線程的,且多個線程都要調(diào)用 Python,你需要處理 GIL (Global Interpreter Lock)。
總結(jié)
通過 Py_Initialize 嵌入 Python,為 C++ 程序打開了一扇通往無限庫資源的大門。雖然 Python C API 的語法略顯繁瑣(尤其是內(nèi)存管理),但它帶來的靈活性是無與倫比的。
到此這篇關(guān)于C++通過 Py_Initialize實現(xiàn)對Python的嵌入調(diào)用的文章就介紹到這了,更多相關(guān)C++嵌入調(diào)用Python內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
利用C語言實現(xiàn)將格式化數(shù)據(jù)和字符串相互轉(zhuǎn)換
這篇文章主要為大家詳細(xì)介紹了2個函數(shù),分別是sprintf和sscanf,可以用來實現(xiàn)將格式化數(shù)據(jù)和字符串相互轉(zhuǎn)換,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-03-03
這篇文章主要介紹了C++強制轉(zhuǎn)換與智能指針示例,智能指針(Smart Pointer)是一種抽象的數(shù)據(jù)類型。在程序設(shè)計中,它通常是經(jīng)由類模板來實現(xiàn),借由模板來達(dá)成泛型,借由類別的析構(gòu)函數(shù)來達(dá)成自動釋放指針?biāo)赶虻拇鎯ζ骰驅(qū)ο?/div> 2022-11-11
C/C++函數(shù)參數(shù)聲明解析int?fun()?與?int?fun(void)?的區(qū)別講解
C++中int fun()和int fun(void)的區(qū)別在于函數(shù)參數(shù)的聲明方式,前者默認(rèn)允許任意參數(shù),而后者表示沒有參數(shù),通過清晰的實例源代碼,詳細(xì)解釋了它們在函數(shù)聲明和調(diào)用中的不同之處,這篇文章介紹了C/C++函數(shù)參數(shù)聲明int?fun()與int?fun(void)的差異,需要的朋友可以參考下2024-01-01
Qt 鼠標(biāo)/觸屏繪制平滑曲線(支持矢量/非矢量方式)
這篇文章主要介紹了Qt 鼠標(biāo)/觸屏繪制平滑曲線(支持矢量/非矢量方式),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04
FFmpeg實現(xiàn)音頻漸響效果參數(shù)值詳解
這篇文章主要為大家介紹了FFmpeg實現(xiàn)音頻漸響效果參數(shù)值詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10最新評論

