【问题标题】:Embedded C: manager for global variables嵌入式 C:全局变量管理器
【发布时间】:2015-07-07 08:14:20
【问题描述】:

我想将全局变量封装在一个“数据管理器模块”中。 只能通过避免所有丑陋的功能进行访问 全局变量问题...所以内容对用户完全隐藏。 有没有现成的概念?这样的实现怎么可能 看起来像? “data-manager-module”中的值应该如何存储?

【问题讨论】:

  • 看起来你正在发明 C++。说真的,您可以在源文件中为此类变量使用static:然后其他编译单元将看不到它们。
  • @Bathsheba OO 是一种进行程序设计的方式,而好的程序设计与语言无关。一些语言仅仅提供方便的特性来简化面向对象的设计。
  • 特别是对于 small 嵌入式系统中的嵌入式 C,这是一个坏主意。仅通过函数访问全局状态通常比访问全局变量要慢。但是,您可以有几个全局变量,通过定义一些struct 来打包全局状态,并有一个该类型的全局变量。
  • @BasileStarynkevitch 性能甚至不应该是一个参数,或者编译器在内联方面做得很差。可悲的是,许多嵌入式编译器的质量有问题,所以你最终可能会根据编译器的糟糕程度调整程序设计。
  • 在这种情况下,您只能通过链接时间优化获得内联(或者通过一些全局函数并提供 static inline 函数来访问它)

标签: c embedded


【解决方案1】:

“数据管理器模块”没有任何意义。实施一个只会扫除地毯下根本糟糕的程序设计,将其隐藏而不是实际清理它。全局变量的主要问题不是用户滥用,而是它们在项目中的模块之间创建了紧密耦合,使其难以阅读和维护,并且还增加了错误“升级”到错误所在模块之外的机会。

程序中的每个数据都属于某个模块,其中“模块”由一个 h 文件和一个相应的 c 文件组成。称它为模块或类或 ADT 或任何你喜欢的东西。常识和 OO 设计都要求变量需要在它们实际所属的模块中声明,句号。

您可以通过在文件范围static 中声明变量来实现这一点,然后实现 setter/getter 函数。这是“穷人的私人封装”,不是线程安全的,但对于嵌入式系统,它在大多数情况下都可以正常工作。这是声明此类变量的嵌入式行业事实标准。

或者更高级的替代方法是,您可以通过在 h 文件中将结构声明为不完整类型并在 C 文件中定义它来进行真正的私有封装。这有时被称为“不透明类型”,并基于对象提供真正的封装,这意味着您可以声明该类的多个实例。 Opaque 类型也可用于实现继承(尽管方式相当繁琐)。

【讨论】:

  • 感谢您的详细回复!你的解释很有道理!
【解决方案2】:

在包含在管理器的 .c 文件中但不包含在其 .h 中的头文件中声明并定义所有变量 这样,它们将仅对经理的职能可见。

【讨论】:

    【解决方案3】:

    您可以使用 getter 和 setter 将所有变量保存在一个结构中的单个源中

    static struct all_globals{
      long long myll;
      /* ... */
    } all_globals; /* Not _really_ global*/
    
    long long getmyll(void){
      return all_globals.myll;
    }
    
    long long setmyll(long long value){
      return all_globals.myll = value;
    }
    

    同样,您可以使用不导出到用户 API 的内部头文件,然后从生成的二进制/库中删除符号

    /* globals.c */
    struct all_globals{
      long long myll;
      /* ... */
    } all_globals; /* Not _really_ global*/
    
    /* globals.h */
    #define getmyll() all_globals.myll
    #define setmyll(value) all_globals.myll = (value)
    

    只要付出足够的努力,最终用户在技术上仍然可以看到,但允许您区分全局变量并将它们放在一起。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-24
      • 2011-01-10
      • 1970-01-01
      • 1970-01-01
      • 2015-06-12
      • 2015-05-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多