系统相关
首页 > 系统相关> > python – PyImport_ImportModule,可以从内存加载模块吗?

python – PyImport_ImportModule,可以从内存加载模块吗?

作者:互联网

我在我的C程序中嵌入了python.

我使用PyImport_ImportModule来加载我在.py文件中编写的模块.
但是如何从内存中加载它?假设我的.py文件是加密的,所以我需要先解密它并将代码提供给python来执行.

此外,如果我可以绕过/拦截或修改导入机制,那将是很好的,因此不会从文件系统加载模块,而是我自己的内存块,我该怎么做?

最佳答案:

以下示例显示如何从C字符串定义模块:

#include <stdio.h>
#include <Python.h>
int main(int argc, char *argv[])
{
    Py_Initialize();
    PyRun_SimpleString("print('hello from python')");

    // fake module
    char *source = "__version__ = '2.0'";
    char *filename = "test_module.py";

    // perform module load
    PyObject *builtins = PyEval_GetBuiltins();
    PyObject *compile = PyDict_GetItemString(builtins, "compile");
    PyObject *code = PyObject_CallFunction(compile, "sss", source, filename, "exec");
    PyObject *module = PyImport_ExecCodeModule("test_module", code);

    PyRun_SimpleString("import test_module; print(test_module.__version__)");

    Py_Finalize();
    return 0;
}

输出:

hello from python
version: 2.0

您可以在文档中阅读约import hooks.您需要使用find_module和load_module方法定义类.像下面这样的东西应该工作:

PyObject* find_module(PyObject* self, PyObject* args) {
    // ... lookup args in available special modules ...
    return Py_BuildValue("B", found);
}

PyObject* load_module(PyObject* self, PyObject* args) {
    // ... convert args into filname, source ...
    PyObject *builtins = PyEval_GetBuiltins();
    PyObject *compile = PyDict_GetItemString(builtins, "compile");
    PyObject *code = PyObject_CallFunction(compile, "sss", source, filename, "exec");
    PyObject *module = PyImport_ExecCodeModule("test_module", code);
    return Py_BuildValue("O", module);
}

static struct PyMethodDef methods[] = {
    { "find_module", find_module, METH_VARARGS, "Returns module_loader if this is an encrypted module"},
    { "load_module", load_module, METH_VARARGS, "Load an encrypted module" },
    { NULL, NULL, 0, NULL }
};

static struct PyModuleDef modDef = {
    PyModuleDef_HEAD_INIT, "embedded", NULL, -1, methods, 
    NULL, NULL, NULL, NULL
};

static PyObject* PyInit_embedded(void)
{
    return PyModule_Create(&modDef);
}

int main() {
    ...
    PyImport_AppendInittab("embedded", &PyInit_embedded);
    PyRun_SimpleString("\
import embedded, sys\n\
class Importer:\n\
    def find_module(self, fullpath):\n\
        return self if embedded.find_module(fullpath) else None\n\
    def load_module(self, fullpath):\n\
        return embedded.load_module(fullpath)\n\
sys.path_hooks.insert(0, Importer())\n\
");
    ...
}

标签:python,c-2,cpython,python-embedding
来源: https://codeday.me/bug/20190516/1115431.html