我需要将以下演示示例从cpp包装到cython以便在Python中使用
class Foo1 : public MFoo<unsigned int> {
public:
constexpr Foo1(unsigned int val) : MFoo{val} {}
}
};
class Foo{
public:
static constexpr Foo1 any {0};
static constexpr Foo1 one {1<<1};
static constexpr Foo1 two {1<<2};
};
这就是我现在拥有的 file.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
我的file.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? 这是相似的,但仍然不是很有用
答案 0 :(得分: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
。