用C封装数据 [英] Data encapsulation in C
问题描述
我目前正在嵌入式系统上工作,板上有一个组件,该组件出现两次.我希望该组件有一个.c和一个.h文件.
I am currently working on an embedded system and I have a component on a board which appears two times. I would like to have one .c and one .h file for the component.
我有以下代码:
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;
这些都是硬件设置.我为此结构创建了两个实例(每个部分一个).
Those are all hardware settings. I create two instances of this struct (one for each part).
现在,我需要在后台保留一个值数组.例如.我可以每秒从该设备读取值,并且我想保留最近的100个值.我希望无法从组件的外部"访问此数据(只能通过组件中的特殊功能).
Now I need to keep an array of values in the background. E.g. I can read values from that device every second and I want to keep the last 100 values. I would like this data to be non-accessible from the "outside" of my component (only through special functions in my component).
我不确定如何进行此处.我真的需要使数组成为我的结构的一部分吗?我想到的是要执行以下操作:
I am unsure on how to proceed here. Do I really need to make the array part of my struct? What I thought of would be to do the following:
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指针.
Yet, I will then be able to access my int32_t pointer from everywhere in my code (also from outside my component) which I do not like.
这是唯一的方法吗?您知道更好的方法吗?
Is this the only way to do it? Do you know of a better way?
谢谢.
推荐答案
对于为微控制器编写硬件驱动程序的特定情况(看来如此),请考虑
For the specific case of writing hardware drivers for a microcontroller, which this appears to be, please consider doing like this.
否则,请使用不透明/不完整类型.您会惊讶地发现,很少有C程序员知道如何实际实现自定义类型的100%私有封装,这令人震惊.这就是为什么关于C缺乏称为私有封装的OO功能的说法一直存在的原因.这个神话源于缺乏C知识,仅此而已.
Otherwise, use opaque/incomplete type. You'd be surprised to learn how shockingly few C programmers there are who know how to actually implement 100% private encapsulation of custom types. This is why there's some persistent myth about C lacking the OO feature known as private encapsulation. This myth originates from lack of C knowledge and nothing else.
这是怎么回事:
ads1248.h
ads1248.h
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
ads1248.c
#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
#include "ads1248.h"
int main()
{
ads1248_options_t* ads = ads1248_init(parameters);
...
ads1248_destroy(ads);
}
现在main中的代码无法访问任何struct成员,所有成员都是100%私有的.它只能创建一个指向struct对象的指针,而不能创建它的实例.如果您熟悉的话,它们可以像C ++中的抽象基类一样精确地工作.唯一的区别是,您将必须手动调用init/destroy函数,而不是使用真正的构造函数/析构函数.
Now the code in main cannot access any of the struct members, all members are 100% private. It can only create a pointer to a struct object, not an instance of it. Works exactly like abstract base classes in C++, if you are familiar with that. The only difference is that you'll have to call the init/destroy functions manually, rather than using true constructors/destructors.
这篇关于用C封装数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!