Question

Je suis un peu de difficulté grave d'obtenir un moteur C ++ basé sur Python 2 pour travailler dans python3. Je sais que l'ensemble de la pile IO a changé, mais tout ce que je semble juste essayer finit par un échec. Ci-dessous le pré-code (python2) et le code postal (python3). J'espère que quelqu'un peut me aider à comprendre ce que je fais wrong.I suis également en utilisant boost::python pour contrôler les références.

Le programme est censé charger un objet Python en mémoire via une carte et sur l'utilisation de la fonction d'exécution, il trouve le fichier chargé dans la mémoire et l'exécute. Je basé mon code de l'exemple du gestionnaire de python Delta3D, où ils se chargent dans un fichier et l'exécuter immédiatement. Je ne l'ai pas vu quelque chose d'équivalent dans python3.


Code de python2 commence ici:

    // 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();
    }

Ensuite, je charge le fichier à partir du std :: carte et tenter de l'exécuter:

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

Code de python3 Commence ici: Voilà ce que j'ai jusqu'à présent sur la base de quelques suggestions ici ... SO question Charge:

        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));

Exécuter:

    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) );

Enfin, l'état général du programme à ce stade est le fichier est chargé dans comme TextIOWrapper et dans la course: section fd qui est retourné est toujours 3 et pour une _fdopen raison ne peut jamais ouvrir le FILE ce qui signifie que je peux « t faire quelque chose comme PyRun_SimpleFile. L'erreur lui-même est un débogage ASSERTION sur _fdopen. Y at-il une meilleure façon de faire tout ce que j'apprécie toute aide.

Si vous voulez voir le programme complet de la version python2 il est sur Github

Était-ce utile?

La solution

Donc, cette question était assez difficile à comprendre et je suis désolé, mais je trouve mon ancien code ne fonctionnait pas tout à fait comme je m'y attendais. Voici ce que je voulais que le code pour le faire. Chargez le fichier python dans la mémoire, le stocker dans une carte, puis à une date ultérieure exécuter ce code dans la mémoire. I, mais il fait maintenant beaucoup de sens accompli cela un peu différemment que prévu.

  1. Ouvrez le fichier en utilisant ifstream, voir le code ci-dessous
  2. Convertir le charbon en un boost :: python :: str
  3. Exécuter le boost :: python :: str avec boost :: python :: exec
  4. Profit ???

Etape 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');

Étape 2)     pb :: str file_str (string (entrée et [0]));     loaded_files_.insert (std :: make_pair (std :: string (fullPath (nom de fichier)), file_str)); Étape 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);

complet Code est situé sur github :

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top