【问题标题】:Incomplete type with size不完整的类型与大小
【发布时间】:2019-03-24 22:08:16
【问题描述】:

我正在编写一个 C 库,并且有一个看起来(大致)像这样的结构:

struct Obj {
    char tag,
    union { 
        int i,
        void *v
    } val
};

我不想通过 API 暴露这个结构的内部,因为用户不需要知道实现,他们可以在未来的版本中改变。用户可以通过 API 中的函数与 struct 进行交互。

我在我的 API 中为其他更大的类型在头文件中使用了不完整的类型,这些类型只能由用户通过指针访问。我不想限制用户通过指针访问Obj,因为Obj 最多可能只有16 个字节。

我无法在这里使用不完整的类型,因为我不知道有一种方法可以只向用户公开结构的大小,而没有字段。

我的问题是: 有没有办法只在 C 中公开具有大小的类型(不知道给用户的结构中的字段),还有其他一些技巧来完成我想要的,或者我应该以完全不同的方式实现它?

如果我没有提供足够的细节或不清楚的地方,请发表评论。

【问题讨论】:

  • 为了给用户“尺寸”,必须提供一些内部信息。为了完全隐藏结构,即使它的大小也必须保密。什么对你来说最重要?
  • 我更喜欢隐藏除大小之外的所有内容,但我不确定这是否可能。我宁愿使用不完整的类型(没有大小,没有字段)而不是公开字段。
  • 旁白:看起来你想要一个“通用”数据/指针。 'v' 对于所有 object 指针来说足够大。如果您还想要足够的空间来存储函数指针,请添加“int (*f)()”。
  • @chux 我已经在这里简化了,但我的实际结构确实在联合中也包含了一个函数指针。
  • 好吧,看来这就是我的解决方案了。

标签: c incomplete-type


【解决方案1】:

标准模式是创建一个为用户分配结构的函数:

struct Obj* obj_new(void) {
  return malloc(sizeof(struct Obj));
}

然后在您的公共标头中将类型保留为不完整。

当然,如果你真的只想公开大小,你可以创建一个返回sizeof(struct Obj)的函数。显然人们可以滥用它(例如,将值硬编码到他们的代码中作为“优化”以避免调用该函数),但这不取决于你。这是偶尔做的事情,通常是为了帮助促进继承。

【讨论】:

  • 是的,这正是我目前所拥有的,但希望避免用户只能通过指针访问它,因为我的结构体很小。
  • 如果您希望它在数组中大量使用,您也可以创建一个struct Obj* obj_newv(size_t n_elems) { return malloc(sizeof(struct Obj) * n_elems); }。但是,如果您希望人们能够将您的结构嵌入到他们的结构中,您必须公开它。
猜你喜欢
  • 1970-01-01
  • 2011-07-13
  • 1970-01-01
  • 2016-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多