代码之家  ›  专栏  ›  技术社区  ›  Joe

为什么多态调用(比如kauth中的listener)有匿名参数,而不是不透明的指针和访问函数?

api c
  •  0
  • Joe  · 技术社区  · 15 年前

    kauth tech note ,但这并不是特别的。这是一个更一般的API设计问题。

    侦听器的作用域是:

    static int MyListener(
        kauth_cred_t   credential,
        void *         idata,
        kauth_action_t action,
        uintptr_t      arg0,
        uintptr_t      arg1,
        uintptr_t      arg2,
        uintptr_t      arg3
    );
    

    这个 arg0 ... arg3 取决于范围(即上下文)。引用文档:

    其余参数的含义取决于范围。在后面的部分。。。例如,对于VFS作用域(KAUTH_scope_VNODE),arg1是对正在操作的VNODE(VNODE_t类型)的引用

    uintptr_t 被打成 unsigned long 但如果我想通过一个更大的结构呢?).

    重要提示:检查与请求相关联的凭据时,请始终使用sys/kauth.h中定义的访问器函数。测试组成员身份时请特别小心。在Tiger中,用户可以分成许多组(比传统的16个组的限制要多得多),并且可以嵌套组。如果要测试用户是否是组的成员,请使用kauth_cred_is member_gid。

    如果我实现了一个API函数,它可以在不同的上下文中用不同的参数调用,那么我将传入一个不透明类型(即 void * )并提供一组函数从中提取数据。这些函数随API的变化而变化,经得起未来的考验。

    那么,有谁能提供一些关于作者为什么会选择这个设计来解决剩下的争论呢?纯粹是速度(毕竟kauth代码路径是非常热的)?

    2 回复  |  直到 15 年前
        1
  •  0
  •   Bart van Ingen Schenau    15 年前

    类型 uintptr_t 是一个无符号整数,它保证足够大以容纳指针。
    这意味着整数可以不费吹灰之力地通过接口传递,但是如果有更大的类型,那么也可以通过指针传递。

    因此,如果整数是常见的情况,那么您将得到两个世界的最佳结果:

    • 对于一般情况没有麻烦,对于传递整数也没有疑问/不一致(将它们伪装成指针,或者将指针传递给整数)
    • 如果需要(引用)更大的结构,仍然可以传递指针。
        2
  •  0
  •   Vijay Mathew Chor-ming Lung    15 年前

    实现接受可变参数数的函数的可移植和可扩展方法是将其声明为可变的:

    #include <stdarg.h>
    
    static int MyListener (kauth_cred_t   credential, void* idata,
                           kauth_action_t action, ...
    {
        va_list ap;
        int count = some_context_dependend_count;
        int j;
    
        va_start(ap, count); 
        for (j = 0; j < count; j++)
            do_something_with_each_optional_arg (va_arg(ap, uintptr_t); 
        va_end(ap);
        return some_result;
    }