在 Cython 中将结构自动转换为字典

rad*_*lus 5 cython

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

%%file test.h

struct mystruct{
  int i;
  int j;  
};
Run Code Online (Sandbox Code Playgroud)

然后你将它包装在 Cython 中:

cdef extern from "test.h" nogil:
  struct mystruct:
    int i
    int j
Run Code Online (Sandbox Code Playgroud)

还有一些返回到 Py 的函数:

def spit_out_dict():
  return mystruct(5,10)
Run Code Online (Sandbox Code Playgroud)

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

%%file test2.h

namespace outerspace{
struct mystruct{
  int i;
  int j;  
};
}
Run Code Online (Sandbox Code Playgroud)

和 Cython/Python:

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

def spit_out_dict():
  return mynewstruct(5,10)
Run Code Online (Sandbox Code Playgroud)

这不会编译 - 很多命名空间投诉错误 - 以前有人遇到过这种情况吗?

Dav*_*idW 3

您的问题是 Cython 似乎只期望命名空间与cppclass. 对于结构,它生成一些函数,但只是复制完整的命名空间名称,从而导致错误:

\n\n
static PyObject* __pyx_convert__to_py_outerspace::mystruct(struct outerspace::mystruct s);\n                  ^\npy_bit.cpp: In function \xe2\x80\x98PyObject* __pyx_pf_6py_bit_spit_out_dict(PyObject*)\xe2\x80\x99:\npy_bit.cpp:721:15: error: \xe2\x80\x98__pyx_convert__to_py_outerspace\xe2\x80\x99 has not been declared\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n

在这种情况下,诀窍通常是对 Cython 撒谎。我创建三个文件:

\n\n
// test2.hpp\nnamespace outerspace{\nstruct mystruct{\n  int i;\n  int j;  \n};\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

,

\n\n
// test2_cy.hpp - a wrapper file purely for Cython\'s benefit\n#include "test2.hpp"\n\nusing outerpsace::mystruct;\n
Run Code Online (Sandbox Code Playgroud)\n\n

和 cython 文件

\n\n
cdef extern from "test2_cy.hpp": # (I didn\'t test with "nogil", but it\'s probably fine...)\n  struct mynewstruct:\n    int i\n    int j\n\ndef spit_out_dict():\n  # for some reason using "return mystruct(5,10)" doesn\'t work, but this does...\n  cdef mystruct a = mystruct(5,10)\n  return a\n
Run Code Online (Sandbox Code Playgroud)\n