Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/api/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么多态调用(比如kauth中的listener)有匿名参数,而不是不透明的指针和访问函数?_C_Api - Fatal编程技术网

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

C 为什么多态调用(比如kauth中的listener)有匿名参数,而不是不透明的指针和访问函数?,c,api,C,Api,我在看电影,但这不是特别的。这更像是一个一般的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 );

我在看电影,但这不是特别的。这更像是一个一般的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\u t
的类型定义为
unsigned long
,但是如果我想传入更大的结构呢?)

此类问题的一个例子可以在同一文件中看到:

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

如果我实现的API函数可以在不同的上下文中使用不同的参数调用,我会传入一个不透明类型(即a
void*
),并提供一组函数从中提取数据。这些函数随API的变化而变化,具有前瞻性


那么,有人能提供一些见解来解释为什么作者会选择这种设计作为剩余的论据吗?是否纯粹是速度问题(kauth代码路径毕竟非常热门)?

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

#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;
}
#包括
静态int MyListener(kauth_cred_t凭证,无效*idata,
考思行动行动。。。
{
va_列表ap;
int count=某些上下文依赖的计数;
int j;
va_启动(ap,计数);
对于(j=0;j
类型
uintpttr\u t
是一个无符号整数,保证足够大,可以同时容纳指针。
这意味着整数可以毫无困难地通过接口传递,但如果您有更大的类型,那么也可以通过指针传递

因此,如果整数是常见的情况,那么您将获得两个方面的最佳效果:

  • 对于常见情况没有任何麻烦,对于传递整数也没有疑问/不一致(将它们伪装成指针,或传递指向整数的指针)
  • 如果需要(引用)更大的结构,仍然可以传递指针