【问题标题】:Structure field aliasing in CC中的结构字段别名
【发布时间】:2012-09-07 06:38:09
【问题描述】:

我的设计包括两层,它们彼此共享一些数据。

下层将一些数据保存在一个结构中:

struct Abc {
    int a;
    int b;
    int c;
};

我需要将Abc 结构的b 字段导出到上层,而不能访问其余字段。 我想在上层创建一个新变量(实际上是别名),它与b 字段位于相同的内存位置。这样两层共享相同的变量。

知道如何在不暴露结构的情况下做到这一点吗?

【问题讨论】:

    标签: c structure


    【解决方案1】:

    最简单的方法是:

    struct Public
    {
        int a;
    };
    
    struct Private
    {
        struct Public p;
        int b;
        int c;
    };
    

    并且依赖于 C 特性,指向结构的指针可以转换为该结构的第一个成员的类型,反之亦然。

    如果Public 结构仅包含一个成员,您可能可以不使用它,但最好是面向未来,您永远不知道何时需要更多公共字段。

    【讨论】:

    • 我不想通过指针访问字段。实际上这个字段本身就是一个指针。制作一个指向这个结构的指针会使界面变得混乱。也不能先填写必填字段。
    • @HimanshuRawat:如果您想从其他地方访问结构变量的成员,您必须使用指针。在 C 中,你不能让两个不同的对象引用同一个内存(除了联合,它们在这里对你没有帮助)。
    • 有没有办法使用链接器指令?我们可以使用 getter 和 setter 强制编译器进行优化吗?
    • @HimanshuRawat:一些编译器/链接器可能有办法指定变量的绝对地址,但这完全是特定于工具的(而且是相当丑陋的 hack)。如果您使用的是 C++,则可以简单地使用全局引用,但在 C 中,通常的方式是使用指针。你甚至可以用宏来伪装指针,但这会更难看! int *my_pointer = &abc.b;, #define myb (*my_pointer)
    【解决方案2】:

    我不确定您在这里所说的层到底是什么意思,但我假设您需要访问 struct 的成员之一,该成员对一个文件是私有的。

    在这种情况下,您可以简单地编写一个extern“peek”函数来返回您想要公开给模块的其他文件的特定结构变量的值。这将保护结构其余部分的范围,同时使该元素的值可访问。

    【讨论】:

    • 你可以认为下层和上层分别是中间件和应用程序。我希望应用程序感觉拥有数据。有点像外部变量。
    【解决方案3】:

    这种访问控制可以直接在 C++ 中实现;这在 C 中是不可行的。您必须使用不访问您不应该访问的成员的纪律。

    有一个部分替代方案:您可以将私有结构变成一个不透明的指针,并拥有一个知道如何获取b 数据的函数。那么上层代码就不需要看到下层数据结构内部的任何东西了。

    upper.h

    #include "lower.h"
    
    struct Upper
    {
        int p;
        struct Lower *q;
        int r;
    };
    

    lower.h

    struct Lower *lower_new(void);
    void lower_free(struct Lower *);
    int lower_b(struct Lower *q);
    

    在上层结构的实例u 中需要下层结构中的b 字段的代码会这样写:

    struct Upper u = { ... };
    int x = lower_b(u.q);
    

    有很多方法可以将该方案调整为适合您的方案。请注意,底层结构的公共标头根本没有定义结构的内容;那是隐藏在源代码中的一个实现细节——大概是lower.c

    【讨论】:

    • 我不想为上层提供任何类型的接口(函数)。由于变量实际上只是内存位置。 “Abc”结构的“b”字段将被分配一些内存位置。我想将此内存位置导出到上层。它类似于 extern(ing) 一个变量。这里唯一的区别是变量不是自变量,而是结构的一部分(字段)。
    • 好的。我或多或少明白你想要什么。我不认为你会发现有一种方法可以在 C 中实现你想要的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-11
    • 2016-01-16
    • 2011-07-24
    • 1970-01-01
    • 2011-01-04
    • 1970-01-01
    • 2018-09-28
    相关资源
    最近更新 更多