首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C语言中的数据封装

C语言中的数据封装
EN

Stack Overflow用户
提问于 2015-03-18 10:14:50
回答 5查看 14.4K关注 0票数 9

我目前正在开发一个嵌入式系统,我在一个板上有一个组件,它会出现两次。我希望组件有一个.c和一个.h文件。

我有以下代码:

代码语言:javascript
复制
typedef struct {
    uint32_t pin_reset;
    uint32_t pin_drdy;
    uint32_t pin_start;
    volatile avr32_spi_t *spi_module;
    uint8_t cs_id;  
} ads1248_options_t;

这些都是硬件设置。我创建这个结构的两个实例(每个部分一个)。

现在,我需要在后台保留一组值。我可以每秒钟从那个设备读取值,我想保留最后的100个值。我希望这些数据不能从组件的“外部”访问(仅通过组件中的特殊功能)。

我不知道该怎么做。我真的需要让数组成为我的结构的一部分吗?我想到的是做以下几件事:

代码语言:javascript
复制
int32_t *adc_values; // <-- Add this to struct

int32_t *adc_value_buffer = malloc(sizeof(int32_t) * 100); // <-- Call in initialize function, this will never be freed on purpose

然而,我将能够访问我不喜欢的代码中的任何地方(也是我的组件之外)的int32_t指针。

这是唯一的办法吗?你知道有更好的方法吗?

谢谢。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2015-03-18 12:17:30

对于为微控制器编写硬件驱动程序的具体情况,请考虑像这样做

否则,使用不透明/不完全类型。您会惊讶地发现,知道如何真正实现定制类型的100%私有封装的C程序员是如此之少。这就是为什么有一些关于C缺乏所谓的私有封装的OO特性的持续神话。这个神话起源于缺乏C知识,而不是其他任何东西。

情况是这样的:

ads1248.h

代码语言:javascript
复制
typedef struct ads1248_options_t ads1248_options_t; // incomplete/opaque type

ads1248_options_t* ads1248_init (parameters); // a "constructor"
void ads1248_destroy (ads1248_options_t* ads); // a "destructor"

ads1248.c

代码语言:javascript
复制
#include "ads1248.h"

struct ads1248_options_t {
    uint32_t pin_reset;
    uint32_t pin_drdy;
    uint32_t pin_start;
    volatile avr32_spi_t *spi_module;
    uint8_t cs_id;  
};

ads1248_options_t* ads1248_init (parameters)
{
  ads1248_options_t* ads = malloc(sizeof(ads1248_options_t));
  // do things with ads based on parameters
  return ads;
}

void ads1248_destroy (ads1248_options_t* ads)
{
  free(ads);
}

main.c

代码语言:javascript
复制
#include "ads1248.h"

int main()
{
  ads1248_options_t* ads = ads1248_init(parameters);
  ...
  ads1248_destroy(ads);
}

现在主要代码不能访问任何结构成员,所有成员都是100%的私有成员。它只能创建指向struct对象的指针,而不能创建结构对象的实例。如果您熟悉抽象基类,那么它的工作方式与C++中的抽象基类完全一样。唯一的区别是,您必须手动调用init/析构函数,而不是使用真正的构造函数/析构函数。

票数 33
EN

Stack Overflow用户

发布于 2015-03-18 11:54:47

通常,C中的结构是完全在头中定义的,尽管它们是完全不透明的(例如,FILE),或者只在文档中指定了它们的一些字段。

C缺乏防止意外访问的private,但我认为这是一个小问题:如果规范中没有提到字段,为什么要有人尝试访问它?您有没有意外地访问过FILE的一个成员?(最好不要做一些事情,比如有一个已发布的成员foo和一个未发布的fooo,这很容易被一个小错误所访问)。有些人使用一些惯例,比如给它们取“不寻常”的名字,例如,在私有成员上有一个尾下划线。

另一种方法是PIMPL成语:正向声明结构为不完整类型,并仅在实现文件中提供完整声明。这可能会使调试复杂化,并且可能会因为内联的可能性减少和额外的间接影响而导致性能下降,尽管这可以通过链接时间优化来解决。还可以同时声明头中的公共字段和指向保存私有字段的不完全结构类型的指针。

票数 2
EN

Stack Overflow用户

发布于 2015-03-18 10:31:09

我希望这些数据不能从组件的“外部”访问(仅通过组件中的特殊功能)。

您可以这样做(包括数据在内的大型malloc ):

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

typedef struct {
    uint32_t pin_reset;
    uint32_t pin_drdy;
    uint32_t pin_start;
    volatile avr32_spi_t *spi_module;
    uint8_t cs_id;  
} ads1248_options_t;

void fn(ads1248_options_t *x)
{
    int32_t *values = (int32_t *)(x + 1);
    /* values are not accesible via a member of the struct */

    values[0] = 10;
    printf("%d\n", values[0]);
}

int main(void)
{
    ads1248_options_t *x = malloc(sizeof(*x) + (sizeof(int32_t) * 100));

    fn(x);
    free(x);
    return 0;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29119284

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档