我正在尝试在Cython中使用Collections-C。
我注意到abstract class Sensor {
String getType();
}
class CADPrototype extends Sensor {
String getType() {
return "Virtual";
}
}
class Accelerometer extends Sensor {
String getType() {
return "Real";
}
}
T foo<T extends Sensor>(T v1, T v2, T bar(T t1, T t2)) {
if (v2 is CADPrototype) {
return v1;
}
return v2;
}
Sensor foo_what_dart_does(Sensor v1, Sensor v2, Sensor bar(Sensor t1, Sensor t2)) {
if (v2 is CADPrototype) {
return v1;
}
return v2;
}
Accelerometer foo_infer_from_argument(Accelerometer v1, Accelerometer v2, Accelerometer bar(Accelerometer t1, Accelerometer t2)) {
if (v2 is CADPrototype) {
return v1;
}
return v2;
}
void main() {
Accelerometer v1 = Accelerometer();
CADPrototype v2 = CADPrototype();
Sensor result;
result = foo(v1, v2, (p1, p2) => p1);
// it works
result = foo_what_dart_does(v1, v2, (p1, p2) => p1);
// Compilation Error: CADPrototype cannot be assigned to type Accelerometer
result = foo_infer_from_argument(v1, v2, (p1, p2) => p1);
}
文件中定义了一些结构,而.c
文件中则定义了它们的别名。当我尝试在.h
文件中定义这些结构并在.pxd
文件中使用它们时,gcc会引发错误:.pyx
。
我能够将问题重现到最小的设置,该设置可以复制外部库和我的应用程序:
storage size of ‘[...]’ isn’t known
/* Note: I can't change this */
struct bogus_s {
int x;
int y;
};
/* Note: I can't change this */
typedef struct bogus_s Bogus;
# This is my code
cdef extern from 'testdef.h':
struct bogus_s:
int x
int y
ctypedef bogus_s Bogus
如果我运行cythonize,我会得到
# This is my code
def fn():
cdef Bogus n
n.x = 12
n.y = 23
print(n.x)
如果我使用Cython manual中的In function ‘__pyx_pf_7sandbox_9cytestdef_fn’:
cytestdef.c:1106:9: error: storage size of ‘__pyx_v_n’ isn’t known
Bogus __pyx_v_n;
^~~~~~~~~
表示法,也会遇到相同的错误。
我在做什么错?
谢谢。
答案 0 :(得分:1)
看看您的Collections-C库的文档,这些都是不透明的结构,您应该纯粹通过指针使用它们(不必知道有指针的大小,而在堆栈上进行分配的时候) 。这些结构的分配是在库函数中完成的。
要更改示例以匹配这种情况:
// C file
int bogus_s_new(struct bogus_s** v) {
*v = malloc(sizeof(struct bogus_s));
return (v!=NULL);
}
void free_bogus_s(struct bogus_s* v) {
free(v);
}
您的H文件将包含这些声明,而pxd文件将包含声明的包装。然后在Cython中:
def fn():
cdef Bogus* n
if not bogus_s_new(&n):
return
try:
# you CANNOT access x and y since the type is
# designed to be opaque. Instead you should use
# the acessor functions defined in the header
# n.x = 12
# n.y = 23
finally:
free_bogus_s(n)