Pickling 定义为具有 PyObject* 成员的 C 结构的 Python 扩展类型

发布于 2024-11-07 10:48:21 字数 1381 浏览 5 评论 0原文

我正在通过 Python 运行 C++ 代码,并且想要 pickle 扩展类型。

因此,我有一个 C++ 结构体 (py_db_manager),其中包含指向数据库对象和对象管理器对象(均用 C++ 编写)的指针,我用 python 类型对象 (t_db_manager) 包装了它们。我的问题是,这个 python 类型需要知道如何腌制两个指针,以便将其发送到一些子多核进程。因此,我使用 copy_reg 模块注册了该类型(这相当于在该类型上编写一个 reduce() 方法。但是,我不太确定要放入其中的内容。我应该构建一个元组吗?使用 PyObject* 或者只是整数指针?有人可以帮忙吗?

typedef struct
{
  PyObject_HEAD
  PyObject* man_inst_ ;
  PyObject* db_inst_ ;

}py_db_manager;`

这是 Py_TypeObject

PyTypeObject t_db_manager = {
    PyObject_HEAD_INIT(0)               /* tp_head */
    0,                                  /* tp_internal */
    ".py_db_manager",                  /* tp_name */
    sizeof(py_db_manager)};

这是 reduce 方法中的代码:

PyObject *pickle_manager(PyObject *module, PyObject *args)
{
    py_db_manager *cpp_manager =0;
    PyObject *values = NULL,
        *tuple = NULL;
    char text[512];

    if (!PyArg_ParseTuple(args, "O!", &t_db_manager, &cpp_manager))
        goto error;
    sprintf(text,"man_inst_, db_inst_");
    if ((values = Py_BuildValue("(sii)", text,
                                cpp_manager->man_inst_, cpp_manager->db_inst_)) == NULL)
        goto error;
    tuple = Py_BuildValue("(OO)", manager_constructor, values);

error:
    Py_XDECREF(values);
    return tuple;
}

I am running C++ code via Python and would like to pickle an extension type.

So I have a C++ struct (py_db_manager) containing pointers to a database object and a object manager object (both written in C++) that I wrapped with a python type object (t_db_manager). My problem is that this python type needs to know how to pickle the two pointers in order to send it to some child multicore processes. So I registered the type with the copy_reg module (this is equivalent to writing a reduce() method on the type. However, I'm not too sure what to put in it. Should I build a tuple with the PyObject* or just the integer pointers?. Can anyone help?

typedef struct
{
  PyObject_HEAD
  PyObject* man_inst_ ;
  PyObject* db_inst_ ;

}py_db_manager;`

Here's the Py_TypeObject

PyTypeObject t_db_manager = {
    PyObject_HEAD_INIT(0)               /* tp_head */
    0,                                  /* tp_internal */
    ".py_db_manager",                  /* tp_name */
    sizeof(py_db_manager)};

And here's the code that would be in the reduce method:

PyObject *pickle_manager(PyObject *module, PyObject *args)
{
    py_db_manager *cpp_manager =0;
    PyObject *values = NULL,
        *tuple = NULL;
    char text[512];

    if (!PyArg_ParseTuple(args, "O!", &t_db_manager, &cpp_manager))
        goto error;
    sprintf(text,"man_inst_, db_inst_");
    if ((values = Py_BuildValue("(sii)", text,
                                cpp_manager->man_inst_, cpp_manager->db_inst_)) == NULL)
        goto error;
    tuple = Py_BuildValue("(OO)", manager_constructor, values);

error:
    Py_XDECREF(values);
    return tuple;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

放手` 2024-11-14 10:48:21

因为这将被传递到另一个进程,所以只腌制整数指针将不会像您希望的那样工作。不同的进程使用不同的内存空间,因此它们看不到相同的东西。

因此,要回答您的问题,您应该腌制完整的对象并从接收端重建它们。

Because this will be passed to another process, pickling just integer pointers will not work as you would want it to. Different processes use different memory space therefore they don't see the same things.

So, to answer your question, you should pickle full objects and reconstruct them from the receiving end.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文