隐藏 C 结构体定义

发布于 2024-12-19 11:52:52 字数 1226 浏览 1 评论 0原文

这是我的设置:

在 public.h 中:

#ifndef PUBLIC_H_
#define PUBLIC_H_

#include "func.h"

/*extern typedef struct _my_private_struct PRIVATE_;*/
typedef struct _my_private_struct PRIVATE_; /* Thanks to larsmans and Simon Richter */
#endif

在 struct.h

#ifndef STRUCT_H_
#define STRUCT_H_

struct _my_private_struct {
    int i;
};
#endif

中 在 func.h 中:

#ifndef FUNC_H_
#define FUNC_H_
#include "struct.h"

/* typedef struct _my_private_struct PRIVATE_; */
extern PRIVATE_ * get_new(int);
#endif

在 func.c 中:

#include <stdlib.h>
#include "func.h"

PRIVATE_ * get_new(int i)
{
    PRIVATE_ *p = (PRIVATE_ *) malloc(sizeof(PRIVATE_));
    if (p == NULL) return NULL;

    p->i = i;

    return p; 
}

在 main.c 中:

#include "public.h"

int main(int argc, char ** argv)
{
    PRIVATE_ *p = get_new(2);
    return 0;
}

当我使用 GCC 编译这些文件时,我收到此错误:

OLD COMPILE ERROR

声明说明符中的多个存储类

编辑后编译错误

“*”标记之前应有“=”、“,”、“;”、“asm”或“__attribute__”

有人可以帮我/解释一下为什么我会遇到这个问题以及如何修复它吗?

Here is my setup:

In public.h:

#ifndef PUBLIC_H_
#define PUBLIC_H_

#include "func.h"

/*extern typedef struct _my_private_struct PRIVATE_;*/
typedef struct _my_private_struct PRIVATE_; /* Thanks to larsmans and Simon Richter */
#endif

In struct.h

#ifndef STRUCT_H_
#define STRUCT_H_

struct _my_private_struct {
    int i;
};
#endif

In func.h:

#ifndef FUNC_H_
#define FUNC_H_
#include "struct.h"

/* typedef struct _my_private_struct PRIVATE_; */
extern PRIVATE_ * get_new(int);
#endif

In func.c:

#include <stdlib.h>
#include "func.h"

PRIVATE_ * get_new(int i)
{
    PRIVATE_ *p = (PRIVATE_ *) malloc(sizeof(PRIVATE_));
    if (p == NULL) return NULL;

    p->i = i;

    return p; 
}

In main.c:

#include "public.h"

int main(int argc, char ** argv)
{
    PRIVATE_ *p = get_new(2);
    return 0;
}

When I compile those file with GCC I'm getting this error:

OLD COMPILE ERROR

multiple storage classes in declaration specifiers

COMPILE ERROR AFTER EDIT

expected '=', ',', ';', 'asm', or '__attribute__' before '*' token

Can someone help me out/explain why I'm getting this and how to fix it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

征棹 2024-12-26 11:52:52

其他答案很好地涵盖了您的问题。不过,请允许我补充一下并回答您的最新评论:

我收到编译错误:在 public.h 中:重新定义 typedef PRIVATE_...

虽然该错误是不言自明的,但可能不太清楚为什么会发生这种情况。考虑一下当您包含 public.h 时会发生什么:

#include "struct.h"
#include "func.h"
typedef struct _my_private_struct PRIVATE_;

如果您跟踪它并完全扩展预处理器,您将得到以下结果:

// struct.h
struct _my_private_struct
{
    int i;
};

// func.h
typedef struct _my_private_struct PRIVATE_;
extern PRIVATE_ * get_new(int);

// public.h
typedef struct _my_private_struct PRIVATE_;

现在应该很明显为什么您会遇到问题。如果 func.h 中没有 typedef,您的 get_new 原型就会失败,因为它还没有看到 PRIVATE。 OTOH,如果您保留 typedef,那么您已经定义了两次。

另外,看起来您正在尝试使该结构对其他代码和模块保持私有。即使您确实修复了构建错误,您也没有真正实现该封装。考虑一下:

int main()
{
    PRIVATE_ *p = get_new(2);
    p->i = 1337;        // HAHA, I just modified your private i.
                        // what are you going to do about it?
}

如果您希望 C 中的数据隐私,请考虑不透明的指针设计。我建议像这样重组您的来源:

// public.h
#ifndef PUBLIC_H_
#define PUBLIC_H_

#include "func.h"

#endif

// func.h
#ifndef FUNC_H_
#define FUNC_H_

struct PRIVATE_NOT_ACCESSIBLE;
typedef struct PRIVATE_NOT_ACCESSIBLE myint_t;

// declare your struct methods here
myint_t* get_new(int);
// ..

#endif

// func.c
#include <stdlib.h>
#include "func.h"

// define this only with functions 
// that's suppose to work with its internal data
struct PRIVATE_NOT_ACCESSIBLE
{
    int i;
};

myint_t * get_new(int i)
{
  // ...
}

现在,如果您尝试这样做:

#include "public.h"

int main()
{
    myint_t *p = get_new(2);
    p->i = 1337;            // Aw, doesn't work anymore :(
}

编辑:回答下面OP的评论。

如果您在多个编译单元中实现了私有结构的方法,您仍然可以通过将私有的定义移动到专用标头来使其工作:

// func_implementation.h
#include "func.h"
struct PRIVATE_NOT_ACCESSIBLE
{
    int i;
};
// internal methods, helper functions you don't want exposed should go here too.
// eg.
void helper_method(myint_t *);

实现私有结构“对象”的源文件将包括“func_implementation.h”。使用 private 的外部客户端代码将仅包含“func.h”。

The other answers cover your problem pretty well. However, allow me to add to them and answer your latest comment:

I'm getting compile error: in public.h: redefinition of typedef PRIVATE_...

While the error is self-explanatory it's probably less clear why that's happening. Consider what happens when you include public.h:

#include "struct.h"
#include "func.h"
typedef struct _my_private_struct PRIVATE_;

If you trace through this and fully expand the preprocessor, this is what you'll get:

// struct.h
struct _my_private_struct
{
    int i;
};

// func.h
typedef struct _my_private_struct PRIVATE_;
extern PRIVATE_ * get_new(int);

// public.h
typedef struct _my_private_struct PRIVATE_;

It should now be obvious why you're running into problems. Without the typedef in func.h, your get_new prototype fails because it hasn't seen PRIVATE yet. OTOH, if you leave the typedef in you've defined it twice.

Also, it looks like you're trying to keep that structure private from other code and modules. Even if you do fix the build errors you haven't really achieved that encapsulation. Consider this:

int main()
{
    PRIVATE_ *p = get_new(2);
    p->i = 1337;        // HAHA, I just modified your private i.
                        // what are you going to do about it?
}

If you want data privacy in C consider an opaque pointer design. I recommend restructuring your source like this:

// public.h
#ifndef PUBLIC_H_
#define PUBLIC_H_

#include "func.h"

#endif

// func.h
#ifndef FUNC_H_
#define FUNC_H_

struct PRIVATE_NOT_ACCESSIBLE;
typedef struct PRIVATE_NOT_ACCESSIBLE myint_t;

// declare your struct methods here
myint_t* get_new(int);
// ..

#endif

// func.c
#include <stdlib.h>
#include "func.h"

// define this only with functions 
// that's suppose to work with its internal data
struct PRIVATE_NOT_ACCESSIBLE
{
    int i;
};

myint_t * get_new(int i)
{
  // ...
}

Now if you try this:

#include "public.h"

int main()
{
    myint_t *p = get_new(2);
    p->i = 1337;            // Aw, doesn't work anymore :(
}

Edit: To answer the OP's comment below.

If you have private struct's methods implemented in more than one compilation unit you can still make it work by moving private's definition to a dedicated header:

// func_implementation.h
#include "func.h"
struct PRIVATE_NOT_ACCESSIBLE
{
    int i;
};
// internal methods, helper functions you don't want exposed should go here too.
// eg.
void helper_method(myint_t *);

Source files that implement your struct private 'object' will include 'func_implementation.h'. External client code that uses private will include 'func.h' only.

山有枢 2024-12-26 11:52:52
  • 您必须以 ; 结束 typedef 语句,
  • extern typedef 没有任何意义,只需执行 typedef 即可。
  • You must end a typedef statement with a ;
  • extern typedef makes no sense, just do a typedef.
土豪 2024-12-26 11:52:52

当前语法不正确,您需要在 typedef 和结构后面添加分号。

The current syntax is incorrect, you need to put a semicolon after the typedefs and the structs.

拥抱我好吗 2024-12-26 11:52:52

有一个';' typedef 之后缺失。

编辑:

struct _my_private_struct {...};

不要使用带前导下划线的名称。它们是为语言或实现保留的。

There is a ';' missing after the typedef.

EDIT:

struct _my_private_struct {...};

Don't use names with a leading underscore. They are reserved for the language or the implementation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文