Domanda

Sto avendo alcuni gravi problemi a trovare un motore di Python 2 sulla base C ++ per il lavoro in python3. So che l'intero stack IO è cambiato, ma tutto mi sembra di provare solo finisce in un fallimento. Di seguito è riportato il codice di pre-(python2) e il codice postale (python3). Sto sperando che qualcuno possa aiutarmi a capire quello che sto facendo wrong.I Sono anche utilizzando boost::python per controllare i riferimenti.

Il programma dovrebbe caricare un oggetto Python in memoria tramite una mappa e poi su utilizzando la funzione di periodo è quindi trova il file caricato in memoria e lo esegue. Ho basato il mio codice fuori un esempio dal manager delta3d pitone, dove si caricano in un file ed eseguirlo immediatamente. Non ho visto niente di equivalente in python3.


Codice python2 Begins qui:

    // what this does is first calls the Python C-API to load the file, then pass the returned
    // PyObject* into handle, which takes reference and sets it as a boost::python::object.
    // this takes care of all future referencing and dereferencing.
    try{
        bp::object file_object(bp::handle<>(PyFile_FromString(fullPath(filename), "r" )));
        loaded_files_.insert(std::make_pair(std::string(fullPath(filename)), file_object));
    }
    catch(...)
    {
        getExceptionFromPy();
    }

Poi ho caricare il file dal std :: map e tentare di eseguirlo:

    bp::object loaded_file = getLoadedFile(filename);
    try
    {
        PyRun_SimpleFile( PyFile_AsFile( loaded_file.ptr()), fullPath(filename) );
    }
    catch(...)
    {
        getExceptionFromPy();
    }

Codice python3 Inizia qui: questo è quello che ho basato finora fuori alcuni suggerimenti qui ... SO domanda Load:

        PyObject *ioMod, *opened_file, *fd_obj;

        ioMod = PyImport_ImportModule("io");
        opened_file = PyObject_CallMethod(ioMod, "open", "ss", fullPath(filename), "r");

        bp::handle<> h_open(opened_file);
        bp::object file_obj(h_open);
        loaded_files_.insert(std::make_pair(std::string(fullPath(filename)), file_obj));

Esegui:

    bp::object loaded_file = getLoadedFile(filename);
    int fd = PyObject_AsFileDescriptor(loaded_file.ptr());
    PyObject* fileObj = PyFile_FromFd(fd,fullPath(filename),"r",-1,"", "\n","", 0);

    FILE* f_open = _fdopen(fd,"r");

    PyRun_SimpleFile( f_open, fullPath(filename) );

Infine, lo stato generale del programma a questo punto è il file viene caricato come TextIOWrapper e nella Run: sezione fd restituito è sempre 3 e per qualche motivo _fdopen potrà mai aprire il FILE che significa che posso 't fare qualcosa di simile PyRun_SimpleFile. L'errore è di per sé un ASSERTION di debug su _fdopen. C'è un modo migliore per fare tutto questo ho davvero apprezzare alcun aiuto.

Se volete vedere il programma completo della versione python2 è su Github

È stato utile?

Soluzione

Quindi questa domanda era piuttosto difficile da capire e mi dispiace, ma ho scoperto che il mio vecchio codice non è stato del tutto funziona come mi aspettavo. Ecco quello che volevo che il codice per fare. Caricare il file di pitone nella memoria, memorizzare in una mappa e poi in un secondo momento di eseguire il codice in memoria. Ho compiuto questo un po 'diverso di quanto mi aspettassi, ma fa un sacco di senso ora.

  1. Apri il file utilizzando ifstream, vedere il codice seguente
  2. Convertire il char in un boost :: :: pitone str
  3. Eseguire il boost :: :: pitone str con boost :: :: python exec
  4. Utile ???

Passo 1)

vector<char> input;
ifstream file(fullPath(filename), ios::in);
if (!file.is_open())
{
    // set our error message here
    setCantFindFileError();
    input.push_back('\0');
    return input;
}

file >> std::noskipws;
copy(istream_iterator<char>(file), istream_iterator<char>(), back_inserter(input));
input.push_back('\n');
input.push_back('\0');

Punto 2)     bp :: file_str str (stringa (& ingresso [0]));     loaded_files_.insert (std :: make_pair (std :: string (fullPath (nome del file)), file_str)); Fase 3)

bp::str loaded_file = getLoadedFile(filename);
// Retrieve the main module
bp::object main = bp::import("__main__");
// Retrieve the main module's namespace
bp::object global(main.attr("__dict__"));
bp::exec(loaded_file, global, global);

Codice completa si trova su github :

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top