使用Cython封装一个库,该库封装另一个库

| 我的目标是使用Cython包装Apohenia库,这是一个用于科学计算的C库。 这是不重建轮子的一种努力,并且Apophenia本身也试图通过基于GNU科学图书馆的结构来做到这一点:
typedef struct {
  gsl_vector *vector;
  gsl_matrix *matrix;
  gsl_vector *weights;
  apop_names *names;
  ...
} apop_data;
Apophenia提供了许多GSL不提供或笨拙地提供的向量/矩阵运算,但是如果GSL具有功能,则没有必要重写它。您应该能够根据需要经常编写在整个often1集及其GSL部分之间跳转的C代码,例如:
apop_data *dataset = apop_text_to_data(\"infile.csv\"); //fill the matrix element
gsl_vector *minv = apop_matrix_inverse(dataset->matrix);
apop_data *dinv = apop_matrix_to_data(minv);
apop_data *identity_matrix = apop_dot(dataset, dinv); // I = D * D^-1
dataset->vector = gsl_vector_alloc(10);
gsl_vector_set_all(dataset->vector, 1);
我不确定如何在Cython中包装它。典型的方法似乎是提供一个Python端结构,其中包含要包装的C结构的内部副本:
\"\"\"I\'m omitting the Cython declarations of the C structs and functions,
 which are just translations of the C declarations. Let those be in c_apop.\"\"\"

cdef class apop_data:
   cdef c_apop.apop_data *d

   def set(self, row, col, val):
       c_apop.apop_data_set(self.d, row, col, val)

   def get(self, row, col):
       c_apop.apop_data_get(self.d, row, col)

   [et cetera]


cdef class gsl_vector:
   cdef c_apop.gsl_vector *v

   def set(self, row, val):
       c_apop.gsl_vector_set(self.v, row)

   def get(self, row):
       c_apop.gsl_vector_get(self.v, row)

   [et cetera]
但是现在我们陷入困境,因为如果要从数据集中获取vector元素,
 pyd = apop_data(10)
 v = pyd.d.vector
v
是原始C
gsl_vector
,而不是python对象,因此下一行不能是
v.get(0)
v.set(0, 1)
。 我们可以将方法添加到名为
vector_get
vector_set
apop_data
类中,这些方法将返回python-wrapped
gsl_vector
,但是会产生自己的问题:如果用户从
pyv = pyd.get_vector()
重新分配py-vector的C向量,我们如何保证
pyd.d.vector
重新分配了吗? 我已经尝试了几件事,但我感觉每次都错过了重点。关于如何针对这种情况最佳设计Cython类的任何建议?     
已邀请:
C结构永远都不应暴露在python端。 我快速浏览了一下该库,似乎没有什么异常。 您必须跟踪的唯一情况是库实际重新分配基础向量的时间。这些函数通常将需要一个指向指针的指针,并将该指针值更新为新的分配结构。 为什么需要公开pyd.get_vector?     

要回复问题请先登录注册