cython 问题:'bool' 不是类型标识符

65 投票
3 回答
43734 浏览
提问于 2025-04-18 12:40

我正在拼命想把一个 std::vector<bool> 类型的类成员暴露给一个 Python 类。

这是我的 C++ 类:

class Test
{
  public:
    std::vector<bool> test_fail;
    std::vector<double> test_ok;
};

虽然我能顺利访问和转换类型为 double(或者 int、float 等)的 test_ok,但对于 bool 类型却不行!

这是我的 Cython 类:

cdef class pyTest:
     cdef Test* thisptr
     cdef public vector[bool] test_fail
     cdef public vector[double] test_ok

     cdef __cinit__(self):
         self.thisptr = new Test()
         self.test_fail = self.thisptr.test_fail # compiles and works if commented
         self.test_ok = self.thisptr.test_ok

     cdef __dealloc__(self):
         del self.thisptr

我遇到的错误是:

Error compiling Cython file:
------------------------------------------------------------
...




cdef extern from *:
    ctypedef bool X 'bool'
            ^
------------------------------------------------------------

vector.from_py:37:13: 'bool' is not a type identifier

我使用的是 Python 2.7.6 和 Cython 0.20.2(也试过 0.20.1)。

我也尝试过使用属性,但也不行。

补充说明:我在 pyx 文件的顶部确实有 from libcpp cimport bool,还有 vector 的导入。

到底出了什么问题?我觉得这可能是个 bug。有没有人知道怎么解决这个问题?谢谢。

3 个回答

51

在Cython中,要定义布尔对象(也就是真或假的值),需要用bint来表示。根据这个链接的说明,bint是“布尔整数”的意思,它会被编译成C语言中的整数,但在Cython中会被当作布尔值来使用。

举个例子:

cdef bint boolean_variable = True

来源:类型 bint

77

在你的 .pyx 文件的顶部,你需要添加一些额外的 C++ 支持。

from libcpp cimport bool

我建议你看看里面的内容,找找你可能需要的其他东西,比如 std::string 和 STL 容器。

3

我找到了一种有效的解决办法,虽然可能不是最优的。

我把pytest类中的成员类型换成了Python的列表。

现在的转换是自动进行的,具体可以参考文档:https://docs.cython.org/en/latest/src/userguide/wrapping_CPlusPlus.html#standard-library

所有的转换都会创建一个新的容器,并把数据复制到里面。容器里的项目会自动转换成相应的类型,这个过程还会递归地转换容器里面的容器,比如一个C++的字符串映射的向量。

所以现在,我的类看起来是这样的:

cdef class pyTest:
     cdef Test* thisptr
     cdef public list test_fail #now ok
     cdef public list test_ok

     cdef __cinit__(self):
         self.thisptr = new Test()
         self.test_fail = self.thisptr.test_fail # implicit copy & conversion
         self.test_ok = self.thisptr.test_ok # implicit copy and conversion

     cdef __dealloc__(self):
         del self.thisptr

撰写回答