在 Cython 中将结构自动转换为字典
Auto Conversion of Structs to Dicts in Cython
所以,如果您有一个 header 文件。
%%file test.h
struct mystruct{
int i;
int j;
};
然后用 Cython 包装它:
cdef extern from "test.h" nogil:
struct mystruct:
int i
int j
还有一些 returns 返回到 Py 的函数:
def spit_out_dict():
return mystruct(5,10)
Cython 正确地自动生成了一个字典包装器。但是,当我将原始 C header 包装在命名空间中时,我无法让 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)
这不会编译 -- 很多命名空间投诉错误 -- 以前有人遇到过这种情况吗?
你的问题是 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
这是 Cython 中的一个错误,已在 https://github.com/cython/cython/commit/fa946e8435a4dcc3497fc7b0f4e87256d40844ba
修复
所以,如果您有一个 header 文件。
%%file test.h
struct mystruct{
int i;
int j;
};
然后用 Cython 包装它:
cdef extern from "test.h" nogil:
struct mystruct:
int i
int j
还有一些 returns 返回到 Py 的函数:
def spit_out_dict():
return mystruct(5,10)
Cython 正确地自动生成了一个字典包装器。但是,当我将原始 C header 包装在命名空间中时,我无法让 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)
这不会编译 -- 很多命名空间投诉错误 -- 以前有人遇到过这种情况吗?
你的问题是 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
这是 Cython 中的一个错误,已在 https://github.com/cython/cython/commit/fa946e8435a4dcc3497fc7b0f4e87256d40844ba
修复