0

所以我正在研究我的第一个 gdk_pixbuf_module。将动画添加到 webp 模块。尽管在头文件和 c 文件中尝试了许多变体,但我不断收到这些链接错误,我认为这些错误与 gdk_pixbuf 宏有关。我的猜测是我做了一些简单的错误,但我无法发现它。帮助表示赞赏。

这是头文件 io-webp-anim.h :

//
// Created by alan on 2021-07-15.
//

#ifndef IO_WEBP_ANIM_H
#define IO_WEBP_ANIM_H

//#include <glib-object.h>
#include <webp/types.h>
#include <webp/decode.h>
#include <webp/encode.h>
#include <webp/mux_types.h>
//#include <webp/mux.h>
#include <webp/demux.h>
#include <string.h>

#define GDK_PIXBUF_ENABLE_BACKEND
//#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gdk-pixbuf/gdk-pixbuf-io.h>
#include <gdk-pixbuf/gdk-pixbuf-animation.h>
#undef  GDK_PIXBUF_ENABLE_BACKEND

typedef struct MyWebPData MyWebPData;
typedef struct _GdkPixbufWebpAnim GdkPixbufWebpAnim;
typedef struct _GdkPixbufWebpAnimClass GdkPixbufWebpAnimClass;

#define GDK_TYPE_PIXBUF_WEBP_ANIM              (gdk_pixbuf_webp_anim_get_type ())
#define GDK_PIXBUF_WEBP_ANIM(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_PIXBUF_WEBP_ANIM, GdkPixbufWebpAnim))
#define GDK_IS_PIXBUF_WEBP_ANIM(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_PIXBUF_WEBP_ANIM))

#define GDK_PIXBUF_WEBP_ANIM_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_PIXBUF_WEBP_ANIM, GdkPixbufWebpAnimClass))
#define GDK_IS_PIXBUF_WEBP_ANIM_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_PIXBUF_WEBP_ANIM))
#define GDK_PIXBUF_WEBP_ANIM_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_PIXBUF_WEBP_ANIM, GdkPixbufWebpAnimClass))

typedef struct _WebPContext WebPContext;
typedef struct _GdkPixbufWebpAnimIter GdkPixbufWebpAnimIter;

struct _GdkPixbufWebpAnim {
    GdkPixbufAnimation      parent_instance;
    WebPContext *context;
    WebPAnimInfo *animInfo;
    WebPAnimDecoderOptions *decOptions;
    WebPAnimDecoder     *dec;       // dec and demuxer have identical lifetimes.
    const WebPDemuxer   *demuxer;
    GdkPixbufWebpAnimIter *webp_iter;
};
struct _GdkPixbufWebpAnimClass {
    GdkPixbufAnimationClass parent_class;
    //GObject parent_class;
};

GType gdk_pixbuf_webp_anim_get_type (void) G_GNUC_CONST;

// GdkPixbufWebpAnimIter -->

typedef struct _GdkPixbufWebpAnimIterClass GdkPixbufWebpAnimIterClass;

#define GDK_TYPE_PIXBUF_WEBP_ANIM_ITER              (gdk_pixbuf_webp_anim_iter_get_type ())
#define GDK_PIXBUF_WEBP_ANIM_ITER(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_PIXBUF_WEBP_ANIM_ITER, GdkPixbufWebpAnimIter))
#define GDK_IS_PIXBUF_WEBP_ANIM_ITER(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_PIXBUF_WEBP_ANIM_ITER))

#define GDK_PIXBUF_GIF_ANIM_ITER_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_PIXBUF_GIF_ANIM_ITER, GdkPixbufGifAnimIterClass))
#define GDK_IS_PIXBUF_GIF_ANIM_ITER_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_PIXBUF_GIF_ANIM_ITER))
#define GDK_PIXBUF_GIF_ANIM_ITER_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_PIXBUF_GIF_ANIM_ITER, GdkPixbufGifAnimIterClass))

G_GNUC_BEGIN_IGNORE_DEPRECATIONS
struct _GdkPixbufWebpAnimIter {     /* FIXME - struct is actually gif type */
    GdkPixbufAnimationIter parent_instance;

    GdkPixbufWebpAnim   *webp_anim;
    WebPIterator        *iter;
    //WebPData            *data; 

    GTimeVal            start_time;
    GTimeVal            current_time;
    GTimeVal            frame_start_time;

    long                position;   // Time in milliseconds into this run of the animation
    long                cur_frame_start;    // start time in millisec.
    gint                cur_duration;
    int                 cur_frame;
    gint                first_loop_slowness;
};
G_GNUC_END_IGNORE_DEPRECATIONS
struct _GdkPixbufWebpAnimIterClass {
    GdkPixbufAnimationIterClass parent_class;
    //GObject parent_class;
};

GType gdk_pixbuf_webp_anim_iter_get_type (void) G_GNUC_CONST;

#endif //IO_WEBP_ANIM_H

这是 io-webp-anim.c 文件的摘录:

#include "io-webp-anim.h"

// ... fcn def's.

static void                    gdk_pixbuf_webp_anim_get_size (GdkPixbufAnimation *animation,
                                     int                 *width,
                                     int                 *height) {
    GdkPixbufWebpAnim *anim = GDK_PIXBUF_WEBP_ANIM (animation);
    if (anim && anim->context) {
        *width = anim->context->features.width;
        *height = anim->context->features.height;
    }
}

// more fcn def's.

static int        gdk_pixbuf_webp_anim_iter_get_delay_time             (GdkPixbufAnimationIter *iter) {
    GdkPixbufWebpAnimIter   *webp_iter;
    webp_iter = GDK_PIXBUF_WEBP_ANIM_ITER (iter);
    int dur = -1;
    if (webp_iter && webp_iter->iter) {
        dur = webp_iter->iter->duration;
    }
    return dur;
}


GDK_PIXBUF_WEBP_ANIM 和 GDK_PIXBUF_WEBP_ANIM_ITER 两个宏执行类型转换,涉及 fcn: gdk_pixbuf_webp_anim_get_type 和 gdk_pixbuf_webp_anim_iter_get_type 。现在在我发现的 gdk_pixbuf 模块的示例中,我没有必要实现这些功能 - 它们似乎是由宏以某种方式自动处理的。

但是我的构建给出了错误(好像我需要专门定义那些 fcns):

ninja -C builddir
ninja: Entering directory `builddir'
[1/7] Compiling C object 'tests/59830eb@@t2@exe/t2.c.o'.
[2/7] Compiling C object 'tests/59830eb@@t1@exe/t1.c.o'.
../tests/t1.c: In function ‘main’:
../tests/t1.c:34:13: warning: unused variable ‘asdf’ [-Wunused-variable]
         int asdf = 1;
             ^~~~
../tests/t1.c:33:20: warning: unused variable ‘image’ [-Wunused-variable]
         GdkPixbuf *image = gdk_pixbuf_animation_get_static_image (anim);
                    ^~~~~
../tests/t1.c:42:13: warning: unused variable ‘delay’ [-Wunused-variable]
         int delay = gdk_pixbuf_animation_iter_get_delay_time(anim_iter);
             ^~~~~
[3/7] Compiling C object 'pixbufloader-webp@sha/io-webp-anim.c.o'.
../io-webp-anim.c:697:1: warning: ‘gdk_pixbuf_webp_anim_iter_class_init’ defined but not used [-Wunused-function]
 gdk_pixbuf_webp_anim_iter_class_init (GdkPixbufWebpAnimIterClass *klass)
 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../io-webp-anim.c:589:1: warning: ‘gdk_pixbuf_webp_anim_iter_init’ defined but not used [-Wunused-function]
 gdk_pixbuf_webp_anim_iter_init (GdkPixbufWebpAnimIter *iter)
 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../io-webp-anim.c:581:1: warning: ‘gdk_pixbuf_webp_anim_init’ defined but not used [-Wunused-function]
 gdk_pixbuf_webp_anim_init (GdkPixbufWebpAnim *anim)
 ^~~~~~~~~~~~~~~~~~~~~~~~~
../io-webp-anim.c:567:1: warning: ‘gdk_pixbuf_webp_anim_class_init’ defined but not used [-Wunused-function]
 gdk_pixbuf_webp_anim_class_init (GdkPixbufWebpAnimClass *klass)
 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[4/7] Linking target libpixbufloader-webp.so.
FAILED: libpixbufloader-webp.so 
cc  -o libpixbufloader-webp.so 'pixbufloader-webp@sha/io-webp-anim.c.o' -Wl,--as-needed -Wl,--no-undefined -shared -fPIC -Wl,--start-group -Wl,-soname,libpixbufloader-webp.so -lgtk-3 -lgdk-3 -lpangocairo-1.0 -lpango-1.0 -latk-1.0 -lcairo-gobject -lcairo -lgdk_pixbuf-2.0 -lgio-2.0 -lgobject-2.0 -lglib-2.0 /usr/lib/x86_64-linux-gnu/libgdk_pixbuf-2.0.so /usr/lib/x86_64-linux-gnu/libgobject-2.0.so /usr/lib/x86_64-linux-gnu/libglib-2.0.so /usr/lib/x86_64-linux-gnu/libwebp.so /usr/lib/x86_64-linux-gnu/libwebpdemux.so -Wl,--end-group
pixbufloader-webp@sha/io-webp-anim.c.o: In function `gdk_pixbuf_webp_image_is_static_image':
/home/alan/projects/webp/aghtest/webp-pixbuf-loader/builddir/../io-webp-anim.c:450: undefined reference to `gdk_pixbuf_webp_anim_get_type'
pixbufloader-webp@sha/io-webp-anim.c.o: In function `gdk_pixbuf_webp_anim_get_static_image':
/home/alan/projects/webp/aghtest/webp-pixbuf-loader/builddir/../io-webp-anim.c:470: undefined reference to `gdk_pixbuf_webp_anim_get_type'
/home/alan/projects/webp/aghtest/webp-pixbuf-loader/builddir/../io-webp-anim.c:473: undefined reference to `gdk_pixbuf_webp_anim_iter_get_type'
pixbufloader-webp@sha/io-webp-anim.c.o: In function `gdk_pixbuf_webp_anim_get_iter':
/home/alan/projects/webp/aghtest/webp-pixbuf-loader/builddir/../io-webp-anim.c:502: undefined reference to `gdk_pixbuf_webp_anim_iter_get_type'
/home/alan/projects/webp/aghtest/webp-pixbuf-loader/builddir/../io-webp-anim.c:503: undefined reference to `gdk_pixbuf_webp_anim_get_type'
pixbufloader-webp@sha/io-webp-anim.c.o: In function `gdk_pixbuf_webp_anim_get_size':
/home/alan/projects/webp/aghtest/webp-pixbuf-loader/builddir/../io-webp-anim.c:518: undefined reference to `gdk_pixbuf_webp_anim_get_type'
pixbufloader-webp@sha/io-webp-anim.c.o: In function `gdk_pixbuf_webp_anim_iter_get_pixbuf':
/home/alan/projects/webp/aghtest/webp-pixbuf-loader/builddir/../io-webp-anim.c:533: undefined reference to `gdk_pixbuf_webp_anim_iter_get_type'
pixbufloader-webp@sha/io-webp-anim.c.o: In function `gdk_pixbuf_webp_anim_iter_get_delay_time':
/home/alan/projects/webp/aghtest/webp-pixbuf-loader/builddir/../io-webp-anim.c:601: undefined reference to `gdk_pixbuf_webp_anim_iter_get_type'
pixbufloader-webp@sha/io-webp-anim.c.o: In function `gdk_pixbuf_webp_anim_iter_on_currently_loading_frame':
/home/alan/projects/webp/aghtest/webp-pixbuf-loader/builddir/../io-webp-anim.c:612: undefined reference to `gdk_pixbuf_webp_anim_iter_get_type'
pixbufloader-webp@sha/io-webp-anim.c.o: In function `gdk_pixbuf_webp_anim_iter_advance':
/home/alan/projects/webp/aghtest/webp-pixbuf-loader/builddir/../io-webp-anim.c:626: undefined reference to `gdk_pixbuf_webp_anim_iter_get_type'
pixbufloader-webp@sha/io-webp-anim.c.o: In function `gdk_pixbuf__webp_image_load_animation':
/home/alan/projects/webp/aghtest/webp-pixbuf-loader/builddir/../io-webp-anim.c:781: undefined reference to `gdk_pixbuf_webp_anim_get_type'
collect2: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.

Process finished with exit code 1

这里发生了什么?

4

1 回答 1

0

找到了答案。必须在 .c 文件顶部附近添加以下宏:

G_DEFINE_TYPE (GdkPixbufWebpAnim, gdk_pixbuf_webp_anim, GDK_TYPE_PIXBUF_ANIMATION)
G_DEFINE_TYPE (GdkPixbufWebpAnimIter, gdk_pixbuf_webp_anim_iter, GDK_TYPE_PIXBUF_ANIMATION_ITER)

于 2021-07-19T20:35:45.943 回答