我正在尝试在 cython 中使用 c 库来实现一种特殊的文件结构:
struct XDRFILE
{
FILE * fp; //< pointer to standard C library file handle
void * xdr; //< pointer to corresponding XDR handle
char mode; //< r=read, w=write, a=append
int * buf1; //< Buffer for internal use
int buf1size; //< Current allocated length of buf1
int * buf2; //< Buffer for internal use
int buf2size; //< Current allocated length of buf2
};
连同打开和关闭此类对象的方法:
XDRFILE* xdrfile_open(const char* path, const char* mode)
int xdrfile_close(XDRFILE* xfp)
现在我希望能够访问此结构中的文件指针并将其传递给 fseek 和 ftell 以操纵文件指针的位置。
到目前为止我所做的是一个带有
的 cython 文件from cython.view cimport array as cvarray
import numpy as np
cimport numpy as np
from libc.stdio cimport FILE, fseek
cdef extern from "xdrfile.h":
ctypedef struct XDRFILE:
FILE* fp #< pointer to standard C library file handle
void* xdr #< pointer to corresponding XDR handle
char mode #< r=read, w=write, a=append
int* buf1 #< Buffer for internal use
int buf1size #< Current allocated length of buf1
int* buf2 #< Buffer for internal use
int buf2size #< Current allocated length of buf2
XDRFILE* xdrfile_open(const char* path, const char* mode)
int xdrfile_close(XDRFILE* xfp)
int xdrfile_read_int(int* ptr, int ndata, XDRFILE* xfp)
def Read( filepath ):
cdef XDRFILE* FH = xdrfile_open(filepath, "r")
cdef np.ndarray[np.int32_t, ndim=1] Header = np.zeros( 23, dtype=np.int32 )
xdrfile_read_int( <int*> Header.data, 23, FH)
print Header ## up to here everything works just fine
#now here starts the problem:
fseek( FH[0].fp, 159240, 0)
fseek( FH.fp , 159240, 0)
# does not work: "dereferencing pointer of incomplete type"
## even more brutal things do not work:
FH.fp[0] += 159240
我在这里错过了什么?开头的声明是错误的还是我传递指针的方式?
好的,谢谢你的建议我已经厌倦了阅读关于 cython handels typedefs 和发现 在Cython documentation几个公式它应该如何工作。但是我仍然无法正确处理:
我之前认为这无关紧要,但这是确切的结构: 有
xdrlib.c:
struct XDRFILE
{
FILE * fp; //< pointer to standard C library file handle
void * xdr; //< pointer to corresponding XDR handle
char mode; //< r=read, w=write, a=append
int * buf1; //< Buffer for internal use
int buf1size; //< Current allocated length of buf1
int * buf2; //< Buffer for internal use
int buf2size; //< Current allocated length of buf2
};
xdrlib.h:
typedef struct XDRFILE XDRFILE;
XDRFILE* xdrfile_open(const char* path, const char* mode)
int xdrfile_close(XDRFILE* xfp)
现在我想用 Cython 扭曲它,这样我就可以做到:
cdef XDRFILE* FH = xdrfile_open(filepath, "r")
fseek(FH.fp, 1000, 0)
在我看来,这将是我之前发布的链接中描述的最后一个案例,因此 struct 和 typedef 具有相同的名称。这表明没有 ctypedef 插入一个“正常的”“cdef struct”:解释:
"If the header uses the same name for the tag and typedef, you won’t be able to include a ctypedef for it – but then, it’s not necessary"
但是这会给我:“未定义类型的错误用法»struct XDRFILE«” 另外:“取消引用指向不完整类型的指针”
请您参考如下方法:
最后一行永远行不通。您不能间接指向 FILE*,更不用说向其添加 long 了。
下一个错误在头文件中。它声明了一个 struct XDRFILE 但没有 typedef 到 XDRFILE,然后使用没有 的 在函数原型(prototype)中。修复后,Cython 0.19.2 可以毫无问题地编译它。XDRFILE struct
