为本地声明制作一个 typedef struct public,但将结构成员访问权限保留给它在其中定义的模块
Making a typedef struct public for local declaration, but keep the structure member access private to the module it is defined in
我有这样一种情况,我希望能够在其他模块中本地声明一个结构,但我只希望定义该结构的模块能够实际访问成员.请注意,这是针对嵌入式应用程序的,因此我无法动态分配内存 (malloc)。
foo.h
typedef struct my_struct T_my_struct;
int GetA(T_my_struct *bar);
int GetB(T_my_struct *bar);
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;
}
bar.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));
}
我知道我可以创建一个本地 T_my_struct 指针并在 foo.c 中分配它,除非我没有如前所述的 malloc。我还意识到我可以在 foo.h 中进行结构定义;但是,我不希望其他模块(即 bar.c)直接访问任何成员。有没有一种方法可以在没有动态内存分配的情况下在 C 中执行此操作?
一种方法是将函数添加到 foo.h
:
T_my_struct *get_bar_instance(void);
其在 foo.c
中的实现是:
T_my_struct *get_bar_instance(void)
{
static T_my_struct x;
return &x;
}
然后在 bar.c
中写 get_bar_instance()
而不是 &local_instance
。
如果多个文件需要一个实例,则为每个文件创建一个函数(或者您可以使用带有整数参数的单个函数)。
为了详细说明我对 Matt 的回答(或您对它的回答)的评论,此解决方案使用隐藏的资源池并处理而不是指针。
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 ) ;
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 ;
}
我有这样一种情况,我希望能够在其他模块中本地声明一个结构,但我只希望定义该结构的模块能够实际访问成员.请注意,这是针对嵌入式应用程序的,因此我无法动态分配内存 (malloc)。
foo.h
typedef struct my_struct T_my_struct;
int GetA(T_my_struct *bar);
int GetB(T_my_struct *bar);
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;
}
bar.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));
}
我知道我可以创建一个本地 T_my_struct 指针并在 foo.c 中分配它,除非我没有如前所述的 malloc。我还意识到我可以在 foo.h 中进行结构定义;但是,我不希望其他模块(即 bar.c)直接访问任何成员。有没有一种方法可以在没有动态内存分配的情况下在 C 中执行此操作?
一种方法是将函数添加到 foo.h
:
T_my_struct *get_bar_instance(void);
其在 foo.c
中的实现是:
T_my_struct *get_bar_instance(void)
{
static T_my_struct x;
return &x;
}
然后在 bar.c
中写 get_bar_instance()
而不是 &local_instance
。
如果多个文件需要一个实例,则为每个文件创建一个函数(或者您可以使用带有整数参数的单个函数)。
为了详细说明我对 Matt 的回答(或您对它的回答)的评论,此解决方案使用隐藏的资源池并处理而不是指针。
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 ) ;
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 ;
}