我需要
OBJECT
可供其他对象使用。要求是 OBJECT
不需要通过任何外部调用进行初始化。所以我从这样开始......
// .h
struct My_Shared_Obj {
bool is_happy;
struct foo *foos;
};
typedef struct My_Shared_Obj *mysharedobj;
// .c
static mysharedobj MSO = NULL;
mysharedobj __instance();
void __mso_do_something();
void __mso_do_something() {
mysharedobj _mso = __instance();
// now do something with struct members
}
mysharedobj *__instance() {
if(MSO == NULL) {
// initialize MSO
}
return MSO;
}
// we have an 'API' as follows
const struct MSO_API API = {
.do_something = &__mso_do_something
};
MSO
static struct My_Shared_Obj *MSO = NULL;
/*
This method makes an assumption that since it can ever only be called by an API function
that the __instance() function has been invoked and that MSO will be a valid object.
*/
void __foo_add(foo *ptr) {
// assume we have next incrementing somewhere
MSO->foos[next] = *ptr;
}
void __mso_do_something() {
struct My_Shared_Obj _mso = __instance();
// hypothetical condition; assume we have a function that provides a foo for us...
if (!_mso->is_happy) {
__foo_add(get_a_foo());
_mso->is_happy = true;
}
}
我很难正确引用
MSO
对象。上面的例子并不是故意的。这就是我所尝试过的(
已更改名称以保护无辜者)。我已经尝试了一段时间,但没有得到我需要的结果。
如果所有成员的初始值都可以写成常量表达式
static struct My_Shared_Obj the_object = { .is_happy = 1, .foos = NULL };
初始化就像在程序开始运行之前一样发生,因此没有函数可以看到未初始化的值。
在同一个翻译单元内,可以直接访问对象。 如果您想将其公开在 TU 之外,那么还提供一个外部函数来执行此操作:
struct My_Shared_Obj *get_mso(void) {
return &the_object;
}
如果任何初始值需要运行时计算
struct My_Shared_Obj *get_mso(void) {
static struct My_Shared_Obj the_object;
static _Bool is_initialized;
if (!is_initialized) {
// ... initialize the_object ...
is_initialized = 1;
}
return &the_object;
}
在函数内部定义共享对象不会给它任何链接,因此即使同一 TU 中的其他函数也无法访问它,除非最终通过
get_mso()
获取指向它的指针。