【问题标题】:How do you define an opaque struct array in C?你如何在 C 中定义一个不透明的结构数组?
【发布时间】:2009-10-09 17:58:40
【问题描述】:

我的头文件中有如下代码:

typedef struct _bn bnode;

我可以的

bnode b;

很好,但是

b[i],其中 i 是一个 int 给我以下错误:

未定义类型“struct _bn”的使用无效

有什么想法吗?

【问题讨论】:

  • 你甚至不能写一个'bnode b;',因为编译器不知道要分配多少空间。不过,您可以写“bnode *bp;”。

标签: c struct compiler-errors opacity


【解决方案1】:

如上所述,b 不是一个数组,因此不能作为一个数组访问。

另外,您希望编译器如何计算出该结构的大小?当您执行bnode b[i] 之类的操作时,会留出一定的空间供以后使用。没有大小。

您的不透明度打算为您做什么?也许如果你进一步解释你想要完成的事情,你会得到一个更有启发性的答案......

【讨论】:

  • 是的,你是对的。我意识到 sizeof() 是不可能的,因此 b[i] 不能工作。
  • 啊,我把括号解释为重载的 operator[] 调用。
  • @joemoe 您可能会考虑使用void* 或类似机制。
  • @tfinniga 是的,这是模棱两可的,所以我试图涵盖这两种情况。
【解决方案2】:

就 API/库而言,通常如果您需要一个不透明的结构,则不允许 API 的用户因此而声明数组或静态实例之类的东西。对结构一无所知是游戏的名称,因此您可能必须定义一些函数来操作它们。大多数声明不透明结构的 C 库通常具有访问器和修改函数。

一个例子来自 Lua(显然 Lua 状态是一种单一使用的结构,但它的想法):

typedef struct lua_State lua_State;
void lua_pushnumber(lua_State *s, lua_Number n);

在这种情况下,如果您决定需要多个 Lua 状态,您可以执行以下操作:

lua_State *states[5];
for(int i = 0; i < 5; i++)
    states[i] = lua_open();

我认为一般的经验法则是,如果您使用不透明的结构,您将只通过指针工作,这几乎是唯一的方法。

【讨论】:

    【解决方案3】:

    听起来你要么想要一个opaque pointer/PIMPL 实现,要么你应该包含适当的头文件。

    C++ 中的结构与类几乎相同,因此应用相同的技术。

    【讨论】:

    • 我宁愿不以那篇文章中描述的方式使用不透明指针,因为它可能会使函数的用户误以为它是一个值类型。
    【解决方案4】:

    您不能定义不透明结构的数组。如果你这样做,你会得到一个错误,例如:

    错误:数组类型的元素类型不完整

    (具体的错误文本会有所不同;上面的来自gcc 4.4.1)。

    但是你可以做的是创建一个指向不透明结构的指针数组。这是可行的,因为结构的细节不会影响指针的大小。

    typedef struct _bn bnode;
    bnode *b[20];
    

    【讨论】:

    • 这是对不透明结构进行操作的常用方式。
    【解决方案5】:

    你必须至少知道 bnode 的大小才能将它们组成一个数组。

    您可以在 bnode 的不透明定义中这样做:

    typedef struct bnode_struct {
       uint8_t opaque_bytes[1024]; /* magically just "know" how big it is. */
    } bnode;
    

    那么你可以这样做:

    bnode b[10];
    

    它会起作用的。

    【讨论】:

    猜你喜欢
    • 2016-03-11
    • 2016-12-26
    • 2017-07-19
    • 1970-01-01
    • 2012-07-27
    • 1970-01-01
    • 1970-01-01
    • 2010-09-28
    • 1970-01-01
    相关资源
    最近更新 更多