C++ Cython无符号字符[16]表示

C++ Cython无符号字符[16]表示,c++,cython,C++,Cython,我的代码中有结构声明: cdef extern from "uuid/uuid.h": ctypedef unsigned char uuid_t[16] cdef extern from "fr_common.h": ctypedef uuid_t fr_id_t ctypedef struct fr_event_t: fr_id_t id size_t action fr_id_t

我的代码中有结构声明:

cdef extern from "uuid/uuid.h":
    ctypedef unsigned char uuid_t[16]


cdef extern from "fr_common.h":
    ctypedef uuid_t fr_id_t

    ctypedef struct fr_event_t:
       fr_id_t id
       size_t action
       fr_id_t object_id
       long long ts
这里我有一个cython类,我需要从
fr\u事件\u t
结构中传递
fr\u id\t id

cdef class Event:
    cdef:
        bytes _id
        int _action
        bytes object_id
        int _ts

    def __cinit__(self, fr_id_t id, int action, fr_id_t object_id, int ts):
        self._id = id
        self._action = action
        self._object_id = object_id
        self._ts = ts
    
    @staticmethod
    cdef Event from_c(fr_event_t fr_event):
        return Event(
            fr_id_t=fr_event.id,
            action=fr_event.action,
            object_id=fr_event.object_id,
            ts=fr_event.ts,

我如何表示以其他方式在函数中传递它的
fr\u id\t
类型?它的表示形式是存储字节的无符号字符uuid\t[16]。传递
fr\u id\u t
无效,cython编译器在将.pyx文件编译为.so时给了我断言错误

AssertionError: (<FileSourceDescriptor:/home/dmitriyravdel/teyefr/teye-fr/python/teyefr/_teyefr.pyx>, 356, 24): (__pyx_v_id == ((unsigned char *)NULL)) && PyErr_Occurred()
AssertionError:(,356,24):((pyx_v_id==((unsigned char*)NULL))&&PyErr_出现()

错误消息是Cython中的一个错误,这使得诊断非常困难。然而,你想做的对我来说没有多大意义

它们的参数必须是Python对象

所有构造函数参数都将作为Python对象传递。这意味着不可转换的C类型,如指针或C++对象,不能从Cython代码传递到构造函数。如果需要,请使用工厂函数来处理对象初始化。在这个函数中直接调用
\uuuu new\uuuu()
,绕过对
\uuuu init\uuuuu()
构造函数的调用,通常会有所帮助

如果代码正常工作,首先将
fr\u event.id
转换为一个Python对象,传递给
\uu cinit\uuu
,然后将其转换回
fr\u id\u t
,然后将其转换为存储它的
字节这不是你想要的这些转换中的一个似乎把Cython搞糊涂了

实际上,您要做的是在
from_c
中创建一个真正空的
事件:

@staticmethod
cdef from_c(fr_event_t event):
    cdef Event e = Event.__new__()  # This only works if __cinit__ is removed or takes no arguments
    e._id = event.id
    # etc
    return e
您也不能将
fr\u id\t
参数设置为
\uu cinit\uu
,因为正是这些参数触发了问题。我认为,从Python(仅Cython)构造
事件
对象是没有意义的,这样您可能根本就不应该有
\uu cinit\uu
。另一种选择是使用一个
\uuu cinit\uu
,它采用Python等效类型
字节
int

cdef class Event:
    cdef bytes _id
    def __cinit__(self, bytes id):
        self._id = id

    @staticmethod
    cdef from_c(fr_event_t event):
        return Event(event.id)

(为了简单起见,我把这个例子进一步简化了)

先生,你错了。您可以将任何cython类型的任何参数传递到
\uu cinit\uu()
中。例如:cinit(const*char a)。例如dunder
\uuuu new\uuuu()
声明不起作用,因为您必须向其传递参数。否<代码>常量字符*
是特别允许的,因为Python字符串可以转换为
常量字符*
。请尝试使用
\uuuuCinit\uuuuuuuu(int*)
获取一个无法将任意C类型传递给
\uuuCinit\uuuuuu
的示例。我的
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu()
工作得很好,因为我删除了
\uu。通过
\uu cinit\uu()
方法,其他类的逻辑工作正常。唯一的问题是我需要找出如何传递
无符号字符id
。那么,为什么不试试我建议的第二个选项,在传递给构造函数之前,
id
转换为
bytes
。在导入包和称为面部识别函数,调用API C++函数填充该结构。Python不能从内存中读取数据吗?我必须在cython中实现内存分配和释放之类的功能吗?