我正在用Python/C API進行一些測試,以瞭解它如何工作以及如何正確使用它。我的目標是創建C++包裝器,它允許我從C++代碼運行Python腳本。 我無法使用外部綁定庫(如Boost.Python或Cython)。一切都很好,除了一兩件事:用PyImport_Import()如何將Python模塊(從PyObject *)轉換並保存爲二進制數據以便稍後使用它?
PyObject* py_module = PyImport_Import(py_module_name); //imports *.py file
//do something, call functions, save results
PyDecRef(py_module);
現在,我加載腳本在發行版本,但是,它們必須分佈在專有的二進制格式,並加載到啓動時的內存。我正在尋找一些提示如何實現這一點 - 沒有結果。基本上,我需要這樣做:
File* file = fopen("scripts.bin", "rb");
char* c_buff = malloc(...);
fread(c_buff, file, ...);
PyObject* py_module = CreatePyObjectFromBinaryData(c_buff, ...);
可能smeone提供可能的解決方案嗎?我想過以這種方式使用編組功能:
FILE* file = fopen("scripts.bin", "wb");
PyMarshal_WriteObjectToFile(py_module, file, Py_MARSHAL_VERSION);
但是,這似乎並不奏效。事實上,我不確定哪些對象可以用這種方式進行編組,因爲文檔沒有提到它。
可選問題:我在我的二進制文件夾中有* .py文件。在啓動時,在PyImport_Import()之後,它們被隱式編譯爲/ pycache中的字節碼(.pyc)。我知道字節碼文件( .pyc或* .pyo)可以使用compileall模塊創建。是否可以使用這種文件的內容創建包含模塊數據的PyObject?
你可以只運送Python腳本? – Yakk
這是我被告知的最初要求之一。我負責'偵察' - 可能的解決方案是什麼以及它們有多複雜。如果解決這個問題不容易實現,我們不會強迫它,只是用'原始'腳本來運送應用程序。這很容易 - Py_CompileStringExFlags和PyEval_EvalCodeEx就是這樣。問題是:是否有可能序列化由Py_CompileStringExFlags返回的代碼對象,並使用它的內容而不是原始文件,這是在應用程序啓動時編譯的。 –
@Mateusz> ...每次應用程序啓動時編譯。 < - 這並不完全正確。如果我正確理解你,並且你指的是.pyc python字節碼,它會被生成一次 - 你甚至可以強制從python本身離線生成。鑑於字節碼可以「輕鬆」反編譯,爲什麼不堅持呢?一個簡單的部署腳本可以複製/生成.py文件並強制啓動.pyc生成。 – MariusSiuram