Python 3 C-API IO 和文件执行
我在让基于 Python 2 的 C++ 引擎在 Python3 中工作时遇到了一些严重的问题。我知道整个 IO 堆栈已经改变,但我似乎尝试的一切都以失败告终。以下是前置代码 (Python2) 和后置代码 (Python3)。我希望有人能帮助我找出我做错了什么。我还使用 boost::python
来控制引用。
该程序应该通过映射将 Python 对象加载到内存中,然后在使用 run 函数时找到加载到内存中的文件并运行它。我的代码基于 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::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) );
最后,此时程序的一般状态是文件作为 TextIOWrapper
加载,并且在 Run: 部分中返回的 fd 始终为 3,并且由于某种原因_fdopen
永远无法打开 FILE
这意味着我无法执行 PyRun_SimpleFile
之类的操作。错误本身是 _fdopen
上的调试 ASSERTION
。有没有更好的方法来完成这一切我真的很感谢任何帮助。
如果您想查看 Python2 版本的完整程序,请访问 Github
I am having some serious trouble getting a Python 2 based C++ engine to work in Python3. I know the whole IO stack has changed, but everything I seem to try just ends up in failure. Below is the pre-code (Python2) and post code (Python3). I am hoping someone can help me figure out what I'm doing wrong.I am also using boost::python
to control the references.
The program is supposed to load a Python Object into memory via a map and then upon using the run function it then finds the file loaded in memory and runs it. I based my code off an example from the delta3d python manager, where they load in a file and run it immediately. I have not seen anything equivalent in Python3.
Python2 Code Begins here:
// 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();
}
Next I load the file from the std::map and attempt to execute it:
bp::object loaded_file = getLoadedFile(filename);
try
{
PyRun_SimpleFile( PyFile_AsFile( loaded_file.ptr()), fullPath(filename) );
}
catch(...)
{
getExceptionFromPy();
}
Python3 Code Begins here: This is what I have so far based off some suggestions here... SO Question
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));
Run:
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) );
Lastly, the general state of the program at this point is the file gets loaded in as TextIOWrapper
and in the Run: section the fd that is returned is always 3 and for some reason _fdopen
can never open the FILE
which means I can't do something like PyRun_SimpleFile
. The error itself is a debug ASSERTION
on _fdopen
. Is there a better way to do all this I really appreciate any help.
If you want to see the full program of the Python2 version it's on Github
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
所以这个问题很难理解,很抱歉,但我发现我的旧代码并没有像我预期的那样工作。这就是我想要代码执行的操作。将 python 文件加载到内存中,将其存储到映射中,然后稍后在内存中执行该代码。我完成的这件事与我的预期有点不同,但现在它很有意义。
步骤 1)
步骤 2)
bp::str file_str(string(&input[0]));
load_files_.insert(std::make_pair(std::string(fullPath(文件名)), file_str));
步骤 3)
完整代码位于 github:
So this question was pretty hard to understand and I'm sorry, but I found out my old code wasn't quite working as I expected. Here's what I wanted the code to do. Load the python file into memory, store it into a map and then at a later date execute that code in memory. I accomplished this a bit differently than I expected, but it makes a lot of sense now.
Step 1)
Step 2)
bp::str file_str(string(&input[0]));
loaded_files_.insert(std::make_pair(std::string(fullPath(filename)), file_str));
Step 3)
Full Code is located on github: