在Cython中自动将结构转换为Dicts

时间:2015-04-13 10:52:36

标签: cython

所以,如果你有一个头文件。

%%file test.h

struct mystruct{
  int i;
  int j;  
};

然后你用Cython包装它:

cdef extern from "test.h" nogil:
  struct mystruct:
    int i
    int j

还有一些返回Py的函数:

def spit_out_dict():
  return mystruct(5,10)

Cython正确自动生成一个dict包装器。但是,当我在命名空间中包装原始C头时,我无法让Cython仍然正确生成dict包装器,这些内容如下:

%%file test2.h

namespace outerspace{
struct mystruct{
  int i;
  int j;  
};
}

和Cython / Python:

cdef extern from "test2.h" namespace "outerspace" nogil:
  struct mynewstruct:
    int i
    int j

def spit_out_dict():
  return mynewstruct(5,10)

这不会编译 - 很多命名空间投诉错误 - 以前有人经历过这个吗?

2 个答案:

答案 0 :(得分:2)

你的问题是Cython似乎只希望命名空间与cppclass一起使用。对于结构体,它会生成一些函数,但只是复制完整的命名空间名称,从而导致错误:

static PyObject* __pyx_convert__to_py_outerspace::mystruct(struct outerspace::mystruct s);
                  ^
py_bit.cpp: In function ‘PyObject* __pyx_pf_6py_bit_spit_out_dict(PyObject*)’:
py_bit.cpp:721:15: error: ‘__pyx_convert__to_py_outerspace’ has not been declared

它试图创建一个名为__pyx_convert__to_py_<classname>的函数。 (我认为这可能值得提交错误报告。)

在这种情况下的诀窍通常是骗到Cython。我创建了三个文件:

// test2.hpp
namespace outerspace{
struct mystruct{
  int i;
  int j;  
};
}

// test2_cy.hpp - a wrapper file purely for Cython's benefit
#include "test2.hpp"

using outerpsace::mystruct;

和cython文件

cdef extern from "test2_cy.hpp": # (I didn't test with "nogil", but it's probably fine...)
  struct mynewstruct:
    int i
    int j

def spit_out_dict():
  # for some reason using "return mystruct(5,10)" doesn't work, but this does...
  cdef mystruct a = mystruct(5,10)
  return a

答案 1 :(得分:2)