2016-06-03 16 views
5

Ho incorporato python nel mio programma C++.PyImport_ImportModule, è possibile caricare il modulo dalla memoria?

Io uso PyImport_ImportModule per caricare il mio modulo scritto in un file .py. Ma come posso caricarlo dalla memoria? Diciamo che il mio file .py è crittografato, quindi ho bisogno di decrittografarlo e dare il codice a Python da eseguire.

Inoltre, sarebbe bello se potessi escludere/intercettare o modificare il meccanismo di importazione, in modo che non carichi i moduli dal filesystem ma i miei blocchi di memoria, come/posso farlo?

risposta

6

Il seguente esempio mostra come definire un modulo da una stringa 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; 
} 

uscita:

hello from python 
version: 2.0 

potete leggere import hooks nella documentazione. Dovrai definire una classe con i metodi find_module e load_module. Qualcosa come il seguente dovrebbe funzionare:

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

Grazie! Il primo esempio funziona perfettamente! – kchkg