我需要为客户端提供一个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!
答案 0 :(得分:7)
如果你正在使用gcc,你可以使用构造函数属性
void runs_before_main(void) __attribute__((constructor))
{
...
}
来自gcc文档
构造函数属性导致 要自动调用的函数 在执行进入main()之前。 同样,析构函数属性 导致调用该函数 在main()之后自动执行 已完成或退出()已被调用。 具有这些属性的函数是 用于初始化将要的数据 在...期间隐式使用 执行该计划。
您可以提供可选的整数 优先控制其中的顺序 构造函数和析构函数 跑了。一个较小的构造函数 优先号在a之前运行 具有更高优先级的构造函数 数;相反的关系 适用于析构函数。所以,如果你有 一个分配一个的构造函数 资源和析构函数 两者都释放相同的资源 功能通常具有相同的功能 优先。优先事项 构造函数和析构函数 与指定的相同 namespace-scope 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
之外访问。
答案 1 :(得分:3)
如果您希望客户端代码能够使用“t.a = ...”,那么您无法隐藏结构定义。你想要的是一个opaque类型,看起来像这样:
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 ); }
结构定义仅适用于库。如果您不使库源代码可用,则可以将其完全隐藏在库的用户之外。
答案 2 :(得分:2)
C中没有可移植的方法来确保您的代码在main()
之前运行。我要做的只是在你的库中保留一个initialised
标志,设置为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;
}