奇怪的 C 演员表(在 Wayland 库中)[已关闭]

Weird C cast (in Wayland library) [closed]

提问人:zonn 提问时间:11/6/2023 最后编辑:zonn 更新时间:11/7/2023 访问量:419

问:


想改进这个问题吗?更新问题,使其仅通过编辑这篇文章来关注一个问题。

11天前关闭。

Wayland 库用于抽象一些结构,例如 .在标题中,官方网站上有未记录的功能,可能是因为它们是多余的,例如(在wl_proxywl_registrywayland.h)

static inline int wl_registry_add_listener(
    struct wl_registry* wl_registry,
    const struct wl_registry_listener* listener,
    void* data) {
        return wl_proxy_add_listener(
            (struct wl_proxy*) wl_registry,
            (void (**)(void)) listener,
            data);
}

我没有得到的是转换,知道这是一个带有参数的函数指针结构,并且有一些函数类似于具有相似结构但具有不同函数类型的函数。我的问题是void (**)(void)wl_registry_listenerwl_display_add_listenerwl_display_listener

  • 为什么不用函数指针数组替换结构体?
  • 为什么这些转换有效?
  • 如何考虑结构中函数的参数?
  • Wayland 如何处理这些不同类型的类型?wl_proxy

我对最后一个问题有一个线索。所有对象都可以用一个数字来跟踪,所以我认为恢复类型并不难。但是我无法想象一种在不检查每个案例的情况下做到这一点的方法,而且我不认为这是实现的方式(-land... :o) )。

我认为真正的问题是:wl_proxy_add_listener是如何工作的?

结构

在:wayland.h

struct wl_registry;
struct wl_display;
struct wl_callback;
/* and so on */
struct wl_registry_listener {
    void (*global)(
        void* data,
        struct wl_registry* wl_registry,
        uint32_t name,
        const char* interface,
        uint32_t version);
    void (*global_remove)(
        void* data,
        struct wl_registry* wl_registry,
        uint32_t name);
};
struct wl_display_listener {
    void (*error)(
        void* data,
        struct wl_display* wl_display,
        void* object_id,
        uint32_t code,
        const char* message);
    void (*delete_id)(
        void* data,
        struct wl_display* wl_display,
        uint32_t id);
};
struct wl_callback_listener {
    void (*done)(
        void* data,
        struct wl_callback* wl_callback,
        uint32_t callback_data);
};

在:wayland-client-core.h

struct wl_proxy;

文档内容

int wl_proxy_add_listener(
    struct wl_proxy* proxy,
    void (**implementation)(void),
    void* data);

proxy代理对象。

implementation要添加到代理的侦听器。

data要与代理关联的用户数据。

成功时返回 0,失败时返回 -1。

将 的 listener 设置为 ,将其用户数据设置为 。如果已设置侦听器,则此函数将失败,并且不会更改任何内容。proxyimplementationdata

implementation是函数指针的向量。对于操作码,应指向给定对象的处理程序。nimplementation[n]n

proxy不得是代理包装器。

来自 wayland.freedesktop.org(这里)。

如何获取标头和源

TL;来自 git(此处)的 DR 和 wl_proxy 声明及其相关函数,请查看 git(此处中的 wayland-client.c

Wayland 标头和源是通过 XML 文件自动生成的。在 Arch Linux 上,一切都在包中。获取和使用waylandwayland.hwayland.c

$ wayland-scanner client-header /usr/share/wayland/wayland.xml wayland.h

$ wayland-scanner private-code /usr/share/wayland/wayland.xml wayland.c

标头已进入且不存在。相反,请看一下 git(这里)。我不知道是否有其他方法可以得到它。wayland-client-core.h/usr/includewayland-client-core.cwayland-client.c

注意:我没有在wl_proxy_add_listener中找到转换为 wl_proxy 的结构声明,这是另一个谜,但可能只是 typedefs 或依赖于编译器的空结构?

C 铸造 韦兰

评论


答: 暂无答案