[英]Wrapping multiple C++ classes into one Python class
Cython允許通過包裝C和C ++庫的函數和類來使用它們。 我想使用的兩個庫是SFML和Box2D。 他們定義了單獨的Vector2類。 是否可以為這兩個庫(甚至可能更多)編寫一個Vector2 Python包裝器? 我的目標是在與不同的庫進行交互時使用單一Python類型的Vector2。
有人已經做過類似的事情嗎? 這將簡化事情並統一我的Python API。 我已經包裝了SFML的一部分,但除此之外,我對Cython還是陌生的。
對於參考, SFML的Vector2看起來像這樣:
template <typename T> class Vector2 {
public:
T x;
T y;
Vector2();
Vector2(T X, T Y);
template <typename U> explicit Vector2(const Vector2<U>& vector);
...
};
和Box2D向量 :
struct b2Vec2 {
float32 x, y;
b2Vec2() {}
b2Vec2(float32 xIn, float32 yIn);
...
};
總覽
總體思路是三個步驟:
聲明書
首先,您需要一個包裝類型的Cython聲明。 一個示例(非常少)如下。
# This is the Cython interface for Vector2
cdef float float32
cdef extern from "Vector2.hpp" nogil:
# if this was an stl vector, use vector[T, ALLOCATOR=*]
# you must list every template type, even one with default values
cdef cppclass Vector2[T]:
ctypedef T value_type
# Add all the overloads, for example, multiplication
Vector2[T, ALLOCATOR] operator*(const T&) const;
cdef extern from "b2Math.h" nogil:
cdef cppclass b2Vec2:
# Add all overloads, for example, multiplication
void operator*=(float)
接口
接下來,您需要將它們包裝到Python包裝器中。 您需要確保它們具有相同的接口,以便一個可以像另一個一樣使用。 Python數據模型是您的朋友。 一個非常簡單的示例是:
cdef class SfmlVector2_32:
# This is a definition for a float32 vector from Sfml
Vector2[float32] c
def __mul__(self, float32 x):
# multiple and assign
B2Vector2_32 copy;
copy.c = c * x
return copy;
cdef class B2Vector2_32:
# This is a definition for a float32 vector from box2
b2Vec2 c
def __mul__(self, float32 x):
# multiple and assign
B2Vector2_32 copy;
copy.c = c;
copy.c *= x
return copy
廣義向量
最后,您需要一個簡單的包裝器類,該包裝器綁定許多向量類型之一並對該類執行正確的操作。 由於Python不是靜態類型的,並且包裝的每個向量的接口都是相同的,因此這很容易:只需在__init__
初始化正確的向量即可。
class Vector2_32:
def __init__(self, framework = 'SFML'):
# ideally, perform a dictionary lookup if you have many classes
# O(1) for dict, if/then is O(n)
if framework == 'SFML':
self.vector = SfmlVector2_32()
elif framework == 'BOX2':
self.vector = B2Vector2_32()
else:
raise TypeError("Unrecognized framework.")
def __mul__(self, float32 x):
Vector2_32 copy
copy.vector = vector * x
return copy
思想
這是一個非常糟糕的示例,因為通常情況下,您是根據__imul__
(就地乘法)實現__mul__
__imul__
(乘法)的,但是卻能使您大致理解。 這段代碼中可能有錯別字,我現在無法訪問機器進行編譯。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.