如何将Python模块(来自PyObject *)转换并保存为二进制数据以便以后使用它?

时间:2014-01-11 20:13:23

标签: python c++ serialization marshalling python-c-api

我正在使用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?

1 个答案:

答案 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进行编码)。

如果你不信任客户,我认为真正安全的东西真的很难(不可能吗?)。