将 typedef struct 设为 public 以用于本地声明,但将结构成员访问权限保留给它在其中定义的模块

rye*_*ger 5 c embedded struct typedef

我有一种情况,我有一个结构,我希望能够在其他模块中本地声明它,但我只希望定义结构的模块能够实际访问成员。请注意,这是针对嵌入式应用程序的,因此我无法动态分配内存 (malloc)。

foo.h

typedef struct my_struct T_my_struct;

int GetA(T_my_struct *bar);
int GetB(T_my_struct *bar);
Run Code Online (Sandbox Code Playgroud)

foo.c

#include "foo.h"

struct my_struct
{
    int a;
    char b;
}

int GetA(T_my_struct *bar)
{
    return bar->a;
}

int GetB(T_my_struct *bar)
{
    return bar->b;
}

void Init(T_my_struct *bar)
{
    bar->a = 5;
    bar->b = 3;
}
Run Code Online (Sandbox Code Playgroud)

酒吧.c:

#include "bar.h"
#include "foo.h"
#include <stdio.h>
#include <stdlib.h>

static T_my_struct local_instance;  // <--storage size of local_instance not know here

int main()
{
    Init(&local_instance);

    printf("A: %d\n", GetA(&local_instance));
}
Run Code Online (Sandbox Code Playgroud)

我知道我可以创建一个本地 T_my_struct 指针并将它分配在 foo.c 中,除非我没有如前所述的 malloc。我也意识到我可以在 foo.h 中定义结构体;但是,我不希望其他模块(即 bar.c)直接访问任何成员。有没有一种方法可以在没有动态内存分配的情况下在 C 中做到这一点?

Cli*_*ord 3

为了详细说明我对马特的答案(或您对它的回应)的评论,该解决方案使用隐藏的资源池并处理而不是指针。

foo.h

typedef int bar_handle_t ;

int getBarHandle() ;
void freeBarHandle( bar_handle_t handle ) ;
int getA( bar_handle_t handle ) ;
int getB( bar_handle_t handle ) ;
Run Code Online (Sandbox Code Playgroud)

foo.c

#include <stdbool.h>
#include "foo.h"

typedef struct
{
    int a;
    char b;
} bar_t ;

typedef struct
{
    bool in_use ;
    bar_t bar ;
} bar_pool_t ;

#define HANDLE_COUNT 20
static bar_pool_t bar_pool[HANDLE_COUNT] ;

bar_handle_t getBarHandle()
{
    bar_handle_t handle ;

    for( handle = 0 ;
         bar_pool[handle].in_use && handle < HANDLE_COUNT; 
         handle++ )
    {
        // do nothing
    }

    if( handle < HANDLE_COUNT )
    {
        bar_pool[handle].in_use = true ;
        bar_pool[handle].bar.a = 5;
        bar_pool[handle].bar.a = 3;
    }
    else
    {
        handle = -1 ;
    }

    return handle ;
} 

void freeBarHandle( bar_handle_t handle )
{
    if( handle >= 0 && handle < HANDLE_COUNT )
    {
        bar_pool[handle].in_use = false ;
    }
}

int getA( bar_handle_t handle )
{
    return bar_pool[handle].bar.a ;
}

int getB( bar_handle_t handle )
{
    return bar_pool[handle].bar.b ;
}
Run Code Online (Sandbox Code Playgroud)