Я должен предоставить статическую библиотеку C клиенту и должен смочь сделать определение структуры недоступным. К тому же я должен смочь выполнить код перед основным при инициализации библиотеки с помощью глобальной переменной.
Вот мой код:
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;
}
Очевидно, этот код не работает..., но показывает то, что я должен сделать... Кто-либо знает, как сделать эту работу? Я гуглю вполне немного, но не могу найти ответ, любая справка значительно ценилась бы.
TIA!
Если вы хотите, чтобы клиентский код мог использовать "t.a = ...", вы не можете скрыть определение структуры. То, что вы хотите, называется непрозрачным типом, который будет выглядеть примерно так:
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 ); }
Определение структуры доступно только библиотеке. Если вы не сделаете исходный код библиотеки доступным, можно полностью скрыть его от пользователей библиотеки.
Если вы используете gcc, вы можете использовать атрибут конструктора,
void runs_before_main(void) __attribute__((constructor))
{
...
}
Из документации gcc
Атрибут конструктора вызывает функция, которая будет вызываться автоматически до того, как выполнение войдет в main (). Точно так же атрибут деструктора вызывает функцию автоматически после того, как main () завершено или был вызван exit (). Функции с этими атрибутами полезно для инициализации данных, которые будут неявно использоваться во время выполнение программы.
Вы можете указать необязательное целое число приоритет для контроля порядка, в котором функции конструктора и деструктора запущены. Конструктор с меньшим номер приоритета запускается перед конструктор с большим приоритетом количество; противоположные отношения выполняется для деструкторов. Итак, если у вас есть конструктор, который выделяет ресурс и деструктор, который освобождает один и тот же ресурс, оба функции обычно имеют одинаковые приоритет. Приоритеты для функции конструктора и деструктора такие же, как те, которые указаны для объекты C ++ в области пространства имен
Если вы хотите скрыть структуру от пользователей, объявите структуру в заголовке, но определите ее в файле c, передавая указатели. Например, к
// 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
нельзя будет получить доступ за пределами foo.c
.
В C нет переносимого способа гарантировать, что ваш код будет работать до main ()
. Я бы просто поддерживал в вашей библиотеке флаг initialized
, установленный в false, а затем отказывался делать что-либо до тех пор, пока не будет вызвана ваша функция init
.
Как в:
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;
}