I have a situation where I have a struct that I want to be able to be declared locally in other modules, but I only want the module where the struct is defined to be able to actually have any access to the members. Note this is for an embedded application so I do not have the ability to dynamically allocate memory (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));
}
I know I could create a local T_my_struct pointer and have it allocated in foo.c, except I do not have malloc as stated earlier. I also realize that I could just make the struct definition in foo.h; however, I do not want the other modules (i.e. bar.c) to directly access any of the members. Is there a way that I can do this in C without dynamic memory allocation?
To elaborate on my comment on Matt's answer (or your response to it), this solution uses a hidden resource pool and handles rather then pointers.
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 ;
}
One approach would be to add a function to foo.h
:
T_my_struct *get_bar_instance(void);
whose implementation in foo.c
is:
T_my_struct *get_bar_instance(void)
{
static T_my_struct x;
return &x;
}
Then in bar.c
you write get_bar_instance()
instead of &local_instance
.
If multiple files need an instance then make one function for each (or you could use a single function with integer argument).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With