【问题标题】:I would like to understand how overriding a set C struct is possible?我想了解如何覆盖集合 C 结构?
【发布时间】:2012-05-12 23:18:30
【问题描述】:

在为 Apache Web 服务器构建模块时,我遇到了几个实例,其中结构的声明说它只需要 const char* 成员,就像在 apr_table_tapr_array_header_t 的声明中一样,但我找到的例子在 mod_security 等各种模块中,甚至新的ap_parse_form_data 函数都表明void * 数据类型被插入到这些结构中。

我的问题是这怎么可能?如果我尝试使用相同的方法,为什么我的 Visual Studio 编译器会报错?

一个很好的例子是带有 create_request 函数的 mod_security,该函数将 void * 存储在 request_rec 注释中。

【问题讨论】:

    标签: c apache apache-modules


    【解决方案1】:

    指针是可转换的,并且每个对象指针类型都可以转换为void*,因为在void* 中存储任何指针都不会丢失信息。也就是说,以下是有效的:

    struct Foo a;
    struct Foo * p = &a;   // p points to a
    
    void * q = p;          // OK, can store the value of p in q
    
    struct Foo * r = q;    // OK too - we can go back, and r points to a
    
    r->n = 1;
    

    因此,在 C 中习惯将指针传递为 void*,因为知道这些指针始终可以保存 任何 其他对象指针值,并且只在需要时将其转换回所需的类型。

    关于 char 指针的最后一句话:将 any 对象指针转换为 char* 并实际上将其取消引用为指向字符数组的指针不是构成类型双关语并且不违反严格的别名规则——这只是允许您访问任何对象的底层二进制表示。

    【讨论】:

    • 那是我的编译器吗?当我尝试使用相同的确切代码来计算过程时,编译器痛苦地抱怨我使用的函数的定义只接受了 apr_table_t*、const char*、const char*。我没有尝试在 windows 上编译代码,但在 Linux 上编译过很多次。
    • @AlexErwin:您能否发布一些实际代码以及您遇到的错误?
    • 我不确定如何在此处执行此操作,因为代码很多。但是 apr_table_t struct apr_table_entry_t { char *key; char *val; apr_uint32_t key_checksum; }; 结构的 sn-p 我目前无法复制错误,但是当我使用类型为 void* 的变量执行此函数 APR_DECLARE(void) apr_table_set(apr_table_t *t, const char *key, const char *val); 时,编译器会犹豫并说我无法做到这一点。会不会是因为我使用的是 C++ 编译器?
    • @AlexErwin:是的,它可以。 C 和 C++ 是不同的语言。这就像用西班牙语词典翻译意大利语来源。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多