如何使用ctypes定义带有函数指针的结构?

时间:2017-12-07 01:44:52

标签: python c ffmpeg libavcodec

我想从Python调用av_find_input_format函数(来自C中编码的dll)。该函数定义如下:

AVInputFormat *av_find_input_format(const char *short_name);

为了成功调用它,我必须将结构AVInputFormat定义为其返回值。 AVInputFormat结构在C中定义如下:

typedef struct AVInputFormat {
    const char *name;
    const char *long_name;
    int flags;
    const char *extensions;
    const struct AVCodecTag * const *codec_tag;
    const AVClass *priv_class; ///< AVClass for the private context
    const char *mime_type;
    struct AVInputFormat *next;
    int raw_codec_id;
    int priv_data_size;
    int (*read_probe)(AVProbeData *);
    int (*read_header)(struct AVFormatContext *);
    int (*read_packet)(struct AVFormatContext *, AVPacket *pkt);
    int (*read_close)(struct AVFormatContext *);
    int (*read_seek)(struct AVFormatContext *, int stream_index, int64_t timestamp, int flags);
    int64_t (*read_timestamp)(struct AVFormatContext *s, int stream_index, int64_t *pos, int64_t pos_limit);
    int (*read_play)(struct AVFormatContext *);
    int (*read_pause)(struct AVFormatContext *);
    int (*read_seek2)(struct AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags);
    int (*get_device_list)(struct AVFormatContext *s, struct AVDeviceInfoList *device_list);
    int (*create_device_capabilities)(struct AVFormatContext *s, struct AVDeviceCapabilitiesQuery *caps);
    int (*free_device_capabilities)(struct AVFormatContext *s, struct AVDeviceCapabilitiesQuery *caps);
} AVInputFormat;

我该怎么办?

补充说明,现在我的Python如下:

import ctypes
class AVInputFormat(ctypes.Structure):
    pass
AVInputFormat._fields_ = [("name", ctypes.c_char_p),
                          ("long_name", ctypes.c_char_p),
                          ('flags', ctypes.c_int),
                          ('extensions', ctypes.c_char_p),
                          ('codec_tag', ctypes.POINTER(AVCodecTag)),
                          ('priv_class', ctypes.POINTER(AVClass)),
                          ('next', ctypes.POINTER(AVInputFormat)),
                          ('raw_codec_id', ctypes.c_int),
                          ('priv_data_size', ctypes.c_int),
                          ('read_probe', ctypes.POINTER(read_probe)),
                          ('read_header', ctypes.POINTER(read_header)),
                          ('read_packet', ctypes.POINTER(read_packet)),
                          ('read_close', ctypes.POINTER(read_close)),
                          ('read_seek', ctypes.POINTER(read_seek)),
                          ('read_timestamp', ctypes.POINTER(read_timestamp)),
                          ('read_play', ctypes.POINTER(read_play)),
                          ('read_pause', ctypes.POINTER(read_pause)),
                          ('read_seek2', ctypes.POINTER(read_seek2)),
                          ('get_device_list', ctypes.POINTER(get_device_list)),
                          ('create_device_capabilities', ctypes.POINTER(create_device_capabilities)),
                          ('free_device_capabilities', ctypes.POINTER(free_device_capabilities))]

avformat_dll = ctypes.cdll.LoadLibrary('avformat-57.dll')
# *av_find_input_format(const char *short_name);
print avformat_dll.av_find_input_format
func = avformat_dll.av_find_input_format
func.restype = ctypes.POINTER(AVInputFormat)
fmt = func('aac')
print fmt.contents.name

但它与ValueError: NULL pointer access

运行错误

0 个答案:

没有答案