如何从 cython 公开静态 constexpr
Posted
技术标签:
【中文标题】如何从 cython 公开静态 constexpr【英文标题】:How to expose static constexpr from cython 【发布时间】:2017-10-26 19:48:16 【问题描述】:我需要将以下演示示例从 cpp 包装到 cython 以便在 Python 中使用
class Foo1 : public MFoo<unsigned int>
public:
constexpr Foo1(unsigned int val) : MFooval
;
class Foo
public:
static constexpr Foo1 any 0;
static constexpr Foo1 one 1<<1;
static constexpr Foo1 two 1<<2;
;
这是我目前拥有的 文件.pxd
cdef extern from "../MFoo.hpp":
cdef cppclass MFoo:
pass
cdef extern from "../header.hpp":
cdef cppclass Foo1(MFoo):
pass
cdef extern from "../header.hpp":
cdef cppclass Foo:
###@staticmethod
Foo1 _any "Foo::any"
Foo1 _one "Foo::one"
Foo1 _two "Foo::two"
###any=_any
### I also need to link my cpp definitions of any,one and two
###to cython file but I am facing Error:Python object cannot be declared extern
我的文件.pyx
def Bar(self,PyFoo1 abc)
return file.Bar(######) # how would I call something like Foo::one
我需要知道如何将其包装在 cython 中。我正在使用How to expose a constexpr to Cython? 这很相似,但仍然不是很有用
【问题讨论】:
我认为问题在于使用静态成员变量,而不是constexpr
。不过,您绝对不能将 staticmethod
装饰器应用于它们。
【参考方案1】:
您的主要问题是 Cython 没有提供表达 C++ 静态成员变量的方法。为了解决这个问题,您可以将它们放在全局范围内并使用字符串来确保生成正确的 C++ 代码。 constexpr
无关紧要 - Cython 不需要知道它。
我创建了一个从您的示例稍微简化的最小示例(例如,它省略了您未提供定义的不相关模板类):
class C
public:
constexpr C(unsigned int)
;
class D
public:
static constexpr C any 0;
static constexpr C one 1<<1;
static constexpr C two 1<<2;
;
inline void bar(const C&)
在 cython 中:
cdef extern from "whatever.hpp":
cdef cppclass C:
pass
cdef cppclass D:
pass
C any "D::any"
C one "D::one"
C two "D::two"
void bar(const C&)
请注意,我没有将 any
、one
和 two
放在 D
中,但要确保字符串创建 C++ 代码 D::any
等。
我认为还有第二个问题是关于如何从 Python 调用 bar
。显然有很多选项,但一种简单的方法是传递一个字符串,并有一个 Cython 函数将字符串与 C++ 值匹配:
# except NULL allows Cython to signal an error to the calling function
cdef const C* get_C_instance(s) except NULL:
if s=="any":
return &any
elif s=="one":
return &one
elif s=="two":
return &two
raise ValueError("Unrecognised string 0".format(s))
def py_bar(s):
return bar(get_C_instance(s)[0])
这不是创建 Python 接口的唯一解决方案 - 例如,您可以创建一个包含 C
的包装类,并为其实例命名为 any
、one
、two
。
【讨论】:
以上是关于如何从 cython 公开静态 constexpr的主要内容,如果未能解决你的问题,请参考以下文章