我正在使用Python / C API进行一些测试,以了解它是如何工作的以及如何正确使用它。我的目标是创建C ++包装器,允许我从C ++代码运行Python脚本。 我不能使用外部bindind库(如Boost.Python或Cython)。一切都很顺利,除了一件事:现在,我正在使用PyImport_Import()
加载脚本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, ...);
可以提供可能的解决方案吗?我想过以这种方式使用编组功能:
FILE* file = fopen("scripts.bin", "wb");
PyMarshal_WriteObjectToFile(py_module, file, Py_MARSHAL_VERSION);
但是,这似乎不起作用。事实上,我不确定哪些对象可以通过这种方式进行编组,因为文档没有说明任何内容。
可选问题:我的二进制文件夹中包含所有* .py文件。在启动时,在PyImport_Import()之后,它们被无情地编译为/ pycache 中的字节码( .pyc)。我知道可以使用compileall模块创建字节码文件( .pyc或* .pyo)。是否可以使用此类文件的内容创建包含模块数据的PyObject?
答案 0 :(得分:0)
只运送.pyc文件是否可以接受?尝试这样的事情:
int size;
unsigned char *python_code;
PyObject *mainobj;
size = load_file("multiply.pyc", &python_code);
Py_Initialize();
codeobj = PyMarshal_ReadObjectFromString(python_code+8, size-8);
mainobj = PyImport_ExecCodeModule("multiply", codeobj);
Py_Finalize();
见这个讨论...... https://groups.google.com/forum/#!topic/comp.lang.python/zhIe_Aa2Ih8 Caersten Haese说:
pyc文件包含以下内容:
1)包含幻数的8字节标头。 2)“元帅” 序列化代码对象。
因此,为了将这些内容转换为代码对象,您需要 跳过8字节标题,然后解组其余标题。
没有使用包含.pyc文件的加密zip文件? (您需要在c ++代码中对pwd进行编码)。
如果你不信任客户,我认为真正安全的东西真的很难(不可能吗?)。