I need to provide a C static library to the client and need to be able to make a struct definition unavailable. On top of that I need to be able to execute code before the main at library initialization using a global variable.
Here's my code:
private.h
#ifndef PRIVATE_H
#define PRIVATE_H
typedef struct TEST test;
#endif
private.c (this should end up in a static library)
#include "private.h"
#include <stdio.h>
struct TEST
{
TEST()
{
printf("Execute before main and have to be unavailable to the user.\n");
}
int a; // Can be modified by the user
int b; // Can be modified by the user
int c; // Can be modified by the user
} TEST;
main.c
test t;
int main( void )
{
t.a = 0;
t.b = 0;
t.c = 0;
return 0;
}
Obviously this code doesn't work... but show what I need to do... Anybody knows how to make this work? I google quite a bit but can't find an answer, any help would be greatly appreciated.
TIA!
If you're using gcc you can use the constructor attribute,
void runs_before_main(void) __attribute__((constructor))
{
...
}
From the gcc documentation
The constructor attribute causes the function to be called automatically be- fore execution enters main (). Similarly, the destructor attribute causes the function to be called automatically after main () has completed or exit () has been called. Functions with these attributes are useful for initializing data that will be used implicitly during the execution of the program.
You may provide an optional integer priority to control the order in which constructor and destructor functions are run. A constructor with a smaller priority number runs before a constructor with a larger priority number; the opposite relationship holds for destructors. So, if you have a constructor that allocates a resource and a destructor that deallocates the same resource, both functions typically have the same priority. The priorities for constructor and destructor functions are the same as those specified for namespace-scope C++ objects
If you want to hide a struct from users, declare the struct in a header but define it in the c file, passing around pointers. As an example:
// foo.h
typedef struct private_foo foo;
foo * create_foo(void);
void free_foo(foo * f);
// foo.c
struct private_foo {
int i;
}
foo * create_foo(void){
foo * f = malloc(sizeof(*foo));
if (f) f->i = 1;
return f;
}
...
foo->i
can then not be accessed outside foo.c
.
If you want the client code to be able to use "t.a = ...", then you cannot hide the struct definition. What you want is called an opaque type, that will look something like this:
public.h: struct foo; set_a( struct foo *, int ); struct foo * new_foo(void); main.c: #include <public.h> int main( void ) { struct foo *k; k = new_foo(); set_a( k, 5 ); }
The structure definition is only available to the library. If you do not make the library source code available, it is possible to completely hide it from the users of the library.
There is no portable way in C to ensure your code will run before main()
. What I would do is just maintain an initialised
flag in your library, set to false, and then refuse to do anything until your init
function has been called.
As in:
static int initialised = 0;
int init (void) {
// do something.
initialised = 1;
return ERR_OK;
}
int all_other_functions (void) {
if (!init)
return ERR_NOT_INITED;
// do something.
return ERR_OK;
}
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