隐藏C结构定义 [英] Hiding C struct definition

查看:120
本文介绍了隐藏C结构定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是我的设置:

在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;
}

当我编译的文件与海湾合作委员会,我得到这个错误:

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

OLD编译错误

多个存储类声明指定

编译错误后编辑

预期=,,,;,前ASM或__attribute__''*'标记

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

有人能帮助我/解释为什么我得到这个问题以及如何解决它?

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

推荐答案

其他答案涉及您的问题pretty好。但是,请允许我加入他们,并回答您的最新评论:

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

我收到编译错误:在public.h:重新定义的typedef PRIVATE _...

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

虽然该错误是不言自明,它可能不太清楚为什么会发生的事情。考虑当包括public.h会发生什么:

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_;

如果您通过跟踪这一点,完全展开preprocessor,这就是你会得到:

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_;

为什么你遇到了问题应该现在是显而易见的。如果没有func.h typedef的,因为它没有看到私人但是你的 get_new 原型失败。 OTOH,如果你离开你已经两次将它定义typedef的。

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.

此外,它看起来像你想保持这一结构与其他code和模块专用。即使你做修复生成错误,你还没有真正实现了封装。试想一下:

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?
}

如果你想在C数据隐私考虑一个不透明的指针设计。我建议你​​重组来源是这样的:

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 :(
}

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

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 *);

这是实现你的结构私人对象的源文件将包括func_implementation.h。使用私人将包括func.h外部客户code只。

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

这篇关于隐藏C结构定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆