1

Python2ベースのC++エンジンをPython3で動作させるのに深刻な問題があります。IOスタック全体が変更されたことは知っていますが、私が試しているように見えるものはすべて失敗に終わってしまいます。以下は、プリコード(Python2)とポストコード(Python3)です。誰かが私が間違っていることを理解するのを手伝ってくれることを願っています。私boost::pythonは参照を制御するためにも使用しています。

プログラムは、マップを介してPythonオブジェクトをメモリにロードし、run関数を使用すると、メモリにロードされたファイルを見つけて実行することになっています。delta3d python managerの例に基づいてコードを作成しました。ここでは、ファイルを読み込んですぐに実行します。Python3で同等のものを見たことがありません。


Python2コードはここから始まります:

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

次に、std :: mapからファイルをロードし、実行を試みます。

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

Python3コードはここから始まります:これは私がここでいくつかの提案に基づいてこれまでに持っているものです... SO質問の ロード:

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

走る:

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

最後に、この時点でのプログラムの一般的な状態は、ファイルがTextIOWrapperRun:セクションとしてロードされることです。返されるfdは常に3であり、何らかの理由で_fdopen開くことがFILEできないため、のようなことはできませんPyRun_SimpleFile。エラー自体はのデバッグASSERTIONです_fdopen。これをすべて行うためのより良い方法はありますか?私は本当に助けに感謝します。

Python2バージョンの完全なプログラムを確認したい場合は、Githubにあります

4

1 に答える 1

0

そのため、この質問を理解するのはかなり難しく、申し訳ありませんが、古いコードが期待どおりに機能していないことがわかりました。これが私がコードに実行させたかったことです。Pythonファイルをメモリにロードし、マップに保存してから、後日、そのコードをメモリで実行します。私はこれを予想とは少し違った方法で達成しましたが、今では非常に理にかなっています。

  1. ifstreamを使用してファイルを開きます。以下のコードを参照してください
  2. charをboost::python::strに変換します
  3. boost :: python::execを使用してboost::python::strを実行します
  4. 利益 ???

ステップ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');

ステップ2)bp :: str file_str(string(&input [0])); load_files_.insert(std :: make_pair(std :: string(fullPath(filename))、file_str)); ステップ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);

完全なコードはgithubにあります:

于 2011-01-06T04:03:20.560 に答える