如何使用封装在源文件之间传递typedef定义?

在提供的链接中-https://embeddedgurus.com/barr-code/2010/11/what-belongs-in-a-c-h-header-file/

Michael Barr指出以下内容:

不要公开传递给一个或多个模块接口功能或从其返回的任何特定于模块的数据结构的内部格式。也就是说,任何头文件中都不应包含“ struct {…} foo;”代码。如果确实有一种类型,则需要传入和传出模块,以便客户端模块可以创建它的实例,则只需在头文件中“ typedef struct foo foo moduleb_type”即可。客户端模块永远不应该知道这种结构的内部格式,而且这种方式也不知道。

我了解的是,如果有一个模块说“ led”要由客户端模块使用,例如说“ main”,则主模块不应该知道模块“ led”的内部工作原理。 这是我按照建议执行的操作,但似乎无法实施:

led.c:

#include "led.h"

typedef enum
{
    RED = 0,GREEN

} e_LedColor_t;

typedef enum
{
    FAST = 0,SLOW,DIRECT,OFF,HEARTBEAT,DOUBLE_BLINK,IDENTIFICATION

} e_Ledmode_t;

struct Led
{
    e_LedColor_t color;
    e_Ledmode_t mode;

};

led.h:

#ifndef LED_H
#define LED_H

typedef struct Led led_t;

#endif

main.c

#include "led.h"

int main() {

    led_t led;

    return 1;
}

我在俗话说的 led_t led; 行中收到错误:
错误:字段的类型'ledt_t'(又名'struct led')不完整

仅由于主模块无法识别Led结构的定义,它会引发错误。但是,如果我做一个定义,那么整个封装的想法就会丢失。肯定有些东西我误会了,但我不知道那是什么。谁能帮我吗?

aaazhq 回答:如何使用封装在源文件之间传递typedef定义?

它可能比Micheal给出的解释还多,但是我认为他的意图是为有经验的从业者制定“规则”,而不是讲授不透明类型-他认为他的听众之间的理解-也许您必须购买他的一本书才能获得完整的骨感;-)

稍后,Micheal在评论中回答了有关该“规则”的问题,并定义了:

typedef struct window* window_handle ;
                     ^

请注意,该类型是指针typedef,而不是实例类型。

文章中的类型foo无法实例化,只能创建一个指针,因此接口将使用类型foo*的参数,而不是foo的参数。例如,这就是stdio的FILE类型的定义和使用方式-您无法创建FILE实例,只能创建FILE*

您可以定义:

typedef struct Led* led_t;

或保留您的typedef并实例化一个led_t*

led_t* led;

在两种情况下,类型均为不透明

第一个隐藏了“句柄” let_t是指针这一事实,这可能是有用的,因为在某些情况下它可能不是指针-它可能是有限长度的资源数组中的整数索引例如。

关键是您只能实例化指向不完整类型的指针,而不能实例化具体实例。

本文链接:https://www.f2er.com/3090371.html

大家都在问