Python 嵌入 C++ try_rich_compare 类型错误

标签 python c++ c

我的程序中有一个错误,这似乎与比较 python 中的两种对象类型有关。这是 gdb 的错误

    Program received signal SIGSEGV, Segmentation fault.
0x00007fffc3acd35c in try_rich_compare (v=0x7fffcc433ec0 <UTOPIA::PyNodeType>, w=0x7fffc3a06ec0 <UTOPIA::PyNodeType>, op=3) at ../Objects/object.c:621
621 ../Objects/object.c: No such file or directory.
(gdb) bt
#0  0x00007fffc3acd35c in try_rich_compare (v=0x7fffcc433ec0 <UTOPIA::PyNodeType>, w=0x7fffc3a06ec0 <UTOPIA::PyNodeType>, op=3) at ../Objects/object.c:621
#1  0x00007fffc3acded7 in do_richcmp (v=0x7fffcc433ec0 <UTOPIA::PyNodeType>, w=0x7fffc3a06ec0 <UTOPIA::PyNodeType>, op=3) at ../Objects/object.c:930
#2  0x00007fffc3ace164 in PyObject_RichCompare (v=0x7fffcc433ec0 <UTOPIA::PyNodeType>, w=0x7fffc3a06ec0 <UTOPIA::PyNodeType>, op=3) at ../Objects/object.c:982
#3  0x00007fffc3b74a24 in cmp_outcome (op=3, v=0x7fffcc433ec0 <UTOPIA::PyNodeType>, w=0x7fffc3a06ec0 <UTOPIA::PyNodeType>) at ../Python/ceval.c:4525
#4  0x00007fffc3b6bbbe in PyEval_EvalFrameEx (f=0x157e990, throwflag=0) at ../Python/ceval.c:2287
#5  0x00007fffc3b6ff3e in PyEval_EvalCodeEx (co=0x7fffc2553510, globals=0x7fffc254b1a8, locals=0x0, args=0x7fffc257c6a0, argcount=2, kws=0x0, kwcount=0, defs=0x0, defcount=0, closure=0x0)
at ../Python/ceval.c:3252
#6  0x00007fffc3aa643b in function_call (func=0x7fffc2552300, arg=0x7fffc257c678, kw=0x0) at ../Objects/funcobject.c:526
#7  0x00007fffc3a64c79 in PyObject_Call (func=0x7fffc2552300, arg=0x7fffc257c678, kw=0x0) at ../Objects/abstract.c:2529
#8  0x00007fffc3a810a1 in instancemethod_call (func=0x7fffc2552300, arg=0x7fffc257c678, kw=0x0) at ../Objects/classobject.c:2602
#9  0x00007fffc3a64c79 in PyObject_Call (func=0x7fffd80df5e0, arg=0x7fffc2550370, kw=0x0) at ../Objects/abstract.c:2529
#10 0x00007fffc3a64de1 in call_function_tail (callable=0x7fffd80df5e0, args=0x7fffc2550370) at ../Objects/abstract.c:2561
#11 0x00007fffc3a651f3 in PyObject_CallMethod (o=0x7fffc255ced0, name=0x7fffcc4659a4 "invoke", format=0x7fffcc4659a2 "O") at ../Objects/abstract.c:2638
#12 0x00007fffcc45d556 in UTOPIA::Python_service_interface::invoke (this=0x14ed610, invocation_=0x16aa6f0, input_=...)
at /home/oni/Projects/utopia/components/libutopia/plugins/python/service_interface.cpp:134

我的程序包含一个对象库。其中一些对象被包装在 python 对象包装器中。我的主 C++ 程序加载这个 python 库以获得这些类型的定义。在这种情况下,有问题的类型如下所示:

 // Node class
    static PyTypeObject PyNodeType =
    {
        PyObject_HEAD_INIT(0)
        0,                                 /* ob_size */
        "utopia.Node",                     /* tp_name */
        sizeof(PyNode),                    /* tp_basicsize */
        0,                                 /* tp_itemsize */
        (destructor) PyNode_dealloc,       /* tp_dealloc */
        0,                                 /* tp_print */
        0,                                 /* tp_getattr */
        0,                                 /* tp_setattr */
        0,                                 /* tp_compare */
        (reprfunc) PyNode_repr,            /* tp_repr */
        0,                                 /* tp_as_number */
        0,                                 /* tp_as_sequence */
        &PyNode_as_mapping,                /* tp_as_mapping */
        0,                                 /* tp_hash  */
        0,                                 /* tp_call */
        0,                                 /* tp_str */
        0,                                 /* tp_getattro */
        0,                                 /* tp_setattro */
        0,                                 /* tp_as_buffer */
        Py_TPFLAGS_DEFAULT,                /* tp_flags */
        "UTOPIA::GenericNode class",       /* tp_doc */
        0,                                 /* tp_traverse */
        0,                                 /* tp_clear */
        0,                                 /* tp_richcompare */
        0,                                 /* tp_weaklistoffset */
        0,                                 /* tp_iter */
        0,                                 /* tp_iternext */
        PyNode_methods,                    /* tp_methods */
        0,                                 /* tp_members */
        0,                                 /* tp_getset */
        0,                                 /* tp_base */
        0,                                 /* tp_dict */
        0,                                 /* tp_descr_get */
        0,                                 /* tp_descr_set */
        0,                                 /* tp_dictoffset */
        (initproc) PyNode_init,            /* tp_init */
        0,                                 /* tp_alloc */
        PyNode_new,                        /* tp_new */
        0,                                 /* tp_free */
        0,                                 /* tp_is_gc */
        0,                                 /* tp_bases */
        0,                                 /* tp_mro */
        0,                                 /* tp_cache */
        0,                                 /* tp_subclasses */
        0,                                 /* tp_weaklist */
        0,                                 /* tp_del */
    };

现在,稍后,C++ 程序加载 python2.7 库并在其内部启动 python。然后它导入这个包装器 python 库。

这意味着这个 PyNodeType 出现在 C++ 程序中,也出现在 C++ 程序中运行的 python 实例中。在某些时候,将这两件事进行比较,程序就会崩溃! :S

不太确定如何解决这个问题,因为两个地方都需要定义。

进一步检查表明,虽然以某种方式推导了类型,但其中一个参数充满了空指针

(gdb) print v
$4 = (PyObject *) 0x7fffcc433ec0 <UTOPIA::PyNodeType>
(gdb) print *v
$5 = {_ob_next = 0x0, _ob_prev = 0x0, ob_refcnt = 2, ob_type = 0x0}
(gdb) print *w
$6 = {_ob_next = 0x7fffd80b3310, _ob_prev = 0x7fffe00aca70, ob_refcnt = 43, ob_type = 0x7fffc3efc0c0 <PyType_Type>}

***更新***

所以当我创建一个对象时,我会查看内存位置

PyNode* newPyNode = PyObject_New(PyNode, &PyNodeType);
(gdb) print &PyNodeType
$4 = (PyTypeObject *) 0x7fffe353cea0 <UTOPIA::PyNodeType>

但是,如果我查看 newPyNode 对象中的 ob_type 字段

(gdb) print *newPyNode
$7 = {_ob_next = 0x7fffe12fd1c8, _ob_prev = 0x7fffe32024e0 <refchain>, ob_refcnt = 1, ob_type = 0x7fffe2a10ec0 <UTOPIA::PyNodeType>, node = 0xef2cc0}

ob_type 不匹配。是什么赋予了?查看类似

的比较函数
PyObject_TypeCheck

...这些内存位置应该相同。

最佳答案

看起来已经修复了。我已将项目的 CPP .so 部分与 python library.so 结合在一起,这似乎解决了问题。前一个 .so 是为了让主项目可以加载 python 脚本,而第二个 .so 是为了允许 python 程序访问所有 utopia 功能(实际上相反)。将两个库连接在一起似乎已经解决了这个问题。

关于Python 嵌入 C++ try_rich_compare 类型错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25430360/

相关文章:

python - 如何在运行时将字符串转换为格式化字符串文字?

c++ - 头文件中的 `static` , `extern` , `const`

c++ - 复制 std::string 时的分配

c - C语言中有没有办法取消连接?

c - 如果 fgetc 读取 0xFF 会发生什么?

python - 将 mysql select 语句的输出存储为 python 列表

python - 如何在不命名 DataFrame 列的情况下使用 Seaborn.lmplot 函数?

c++ - C 中优雅的二进制 i/o?

c - 如果我们使用 malloc 分配结构体,那么结构体字段会分配在内存的什么位置?

python - 对 python 中正则表达式匹配的唯一值进行排序