2011-01-05 12 views
0

Python 3で動作するPython 2ベースのC++エンジンを取得する際に重大な問題が発生しています。私はIOスタック全体が変更されたことを知っていますが、私が試してみたようなものはすべて失敗に終わります。以下は、プリコード(Python2)とポストコード(Python3)です。私は誰かが私が間違っていることを理解するのを助けることを望んでいます。私はまた参照を制御するためにboost::pythonを使用しています。Python 3のC-API IOとファイルの実行

プログラムは、マップを介してPythonオブジェクトをメモリにロードし、実行関数を使用すると、メモリにロードされたファイルを見つけて実行します。 delta3d pythonマネージャーのコードから、コードをロードしてすぐに実行します。私は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 ::マップからファイルをロードし、それを実行しよう:

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

のpython3コードはここから始まります:これは私が今ここにいくつかの提案に基づいているものです... SO Question 負荷:

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

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

あなたはPython2バージョンの完全なプログラムを見たい場合は、だから、この質問を理解するのはかなり大変だったと私は申し訳ありませんが、私は私の古いコードはかなりとして働いていなかったが分かったGithub

+0

私はあなたがやろうとしているものとで混乱しています。上記のPython 3の例のどれが、上記のPython 2の例のどれを置き換えると思われますか?彼らはまったく異なっています。実際のエラーメッセージは何ですか? –

+0

フェア十分に、私はいくつかの編集を作り、私が達成しようとしているものに、もう少し二段落で説明しました。 –

+0

私は解決策を発見したかもしれないが、私は家に帰るまで、私はそれをテストすることはできません。私はそれを投稿します。 –

答えて

0

上です私は期待した。コードでやりたいことは次のとおりです。 Pythonファイルをメモリにロードしてマップに格納し、後でそのコードをメモリ内で実行します。私は期待したものとは少し違ってこれを達成しましたが、それは今では非常に意味があります。

  1. オープンはifstreamを使用してファイル、
  2. 以下のコードはブーストに文字を変換する::のpythonを参照してください:: strの
  3. は、ブーストを実行します::のpython ::ブースト::の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(文字列(&入力[0])); loaded_files_挿入(STD :: make_pair(STD ::文字列(をフルパス(ファイル名))、file_str)); ステップ3)全コードがgithubに位置しています

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

関連する問題