Skip to main content
 首页 » 编程设计

python之如何在 cython 的结构中使用文件指针

2025年05月04日6pengyingh

我正在尝试在 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,然后使用没有 的 XDRFILE struct 在函数原型(prototype)中。修复后,Cython 0.19.2 可以毫无问题地编译它。