2011-01-05 105 views
0

我在Python3中使用基于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(); 
    } 

接下来,我从性病::地图加载该文件,并试图执行它:

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由于某种原因,_fdopen永远不能打开FILE,这意味着我不能做类似PyRun_SimpleFile的事情。错误本身是_fdopen上的调试ASSERTION。有没有更好的方法来做这一切,我真的很感谢任何帮助。

如果你想看到Github

+0

我在给你正在尝试做的困惑。上面哪个Python 3示例应该取代上面的Python 2示例中的哪一个?他们都如此不同。你的实际错误信息是什么? – 2011-01-05 15:37:14

+0

够公平的,我做了一些编辑,并在第二段中解释了我想要完成的事情。 – 2011-01-05 15:42:18

+0

我可能找到了解决方案,但我无法测试它,直到我回家。当我这样做,我会发布它。 – 2011-01-05 20:35:32

回答

0

的Python2版本,它是完整的程序,所以这个问题是相当困难的理解,我很抱歉,但我发现我的旧代码是不是很为工作我期望。这就是我想要的代码。将python文件加载到内存中,将其存储到映射中,然后在内存中执行该代码。我完成了这个比我预期的有点不同,但它现在很有意义。

  1. 打开使用ifstream的文件,请参见下面
  2. 代码转换的焦炭引入一个boost ::蟒蛇::海峡
  3. 用的boost ::蟒蛇执行的boost ::蟒蛇::海峡:: exec
  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 :: 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