[英]Initialize nontrivial class members when created by PyObject_NEW
我有一个 Python object 指代一个 C++ object。
Header:
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <structmember.h>
typedef struct {
PyObject_HEAD
FrameBuffer frame_buffer;
} PyFrameBuffer;
extern PyTypeObject PyFrameBuffer_type;
extern PyObject* PyFrameBuffer_NEW(size_t width, size_t height);
C++ FrameBuffer
class 如下:
class FrameBuffer {
public:
explicit FrameBuffer(const size_t width, const size_t height);
// ...
private:
size_t m_width;
size_t m_height;
std::vector<Pixel> m_pixels;
};
Pixel
是一个简单的 class 几个普通类型元素。
PyFrameBuffer_NEW()
function 如下:
PyObject* PyFrameBuffer_NEW(size_t width, size_t height)
{
auto* fb = (PyFrameBuffer*) PyObject_NEW(PyFrameBuffer, &PyFrameBuffer_type);
if (fb != nullptr)
{
fb->frame_buffer = FrameBuffer(width, height);
}
return (PyObject*) fb;
}
此代码崩溃:
fb->frame_buffer
分配有未定义的值( fb->frame_buffer.m_pixels.size()
未定义)。
在fb->frame_buffer
赋值期间,在m_pixels
中有一个未定义数量的Pixel
被重新分配。
因此,它崩溃了。
这段代码似乎有效:
/// ...
if (fb != nullptr)
{
FrameBuffer fb_tmp(width, height);
std::memcpy(&fb->frame_buffer, &fb_tmp, sizeof(FrameBuffer));
}
// ...
但我怀疑这不是解决这个问题的正确方法(我怀疑 fb_tmp 中的Pixel
s 在fb_tmp
之外被取消分配。
我已经成功地使用了类似于
typedef struct {
PyObject_HEAD
FrameBuffer *frame_buffer;
} PyFrameBuffer;
然后
if (fb != nullptr)
{
fb->frame_buffer = new FrameBuffer( ... );
}
但是您必须明确删除 object。 您需要将tp_dealloc()
function添加到PyFrameBuffer
初始化中,以删除 C++ FrameBuffer
object:
delete fb->frame_buffer;
还:
当您使用 C++ 创建 Python 扩展模块时,您正在链接代码的 C++ 运行时库。 如果多个模块使用 C++,则它们都必须使用完全相同的 C++ 运行时库。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.