2016-06-03 13 views
5

Wbudowany python w moim programie C++.PyImport_ImportModule, możliwe ładowanie modułu z pamięci?

Używam PyImport_ImportModule do załadowania mojego modułu zapisanego w pliku .py. Ale jak mogę ją załadować z pamięci? Załóżmy, że mój plik .py jest zaszyfrowany, więc muszę go odszyfrować i podać kod Pythona do wykonania.

Co więcej, byłoby miło, gdybym mógł ominąć/przechwycić lub zmodyfikować mechanizm importu, tak aby nie ładował modułów z systemu plików, ale moje własne bloki pamięci, jak/mogę to zrobić?

Odpowiedz

6

Poniższy przykład pokazuje jak zdefiniować moduł z ciągiem 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; 
} 

wyjściowa:

hello from python 
version: 2.0 

Można przeczytać o import hooks w docs. Będziesz musiał zdefiniować klasę metodami find_module i load_module. Powinno działać coś takiego:

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\ 
"); 
    ... 
} 
+0

Dzięki! Pierwszy przykład działa idealnie! – kchkg

Powiązane problemy