定义一个结构为图书馆最好的地方 [英] Best place to define a struct for a library

查看:80
本文介绍了定义一个结构为图书馆最好的地方的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前我正在写一库的通信协议。对于这项任务,我需要这样的结构:

Currently I am writing a library for a communication protocol. For this task I need this struct:

typedef struct _C8B10 {
    unsigned int six :6;
    unsigned int four :4;
} C8B10;

但我应该在哪里定义的?我有一个'主'*由所有其他库包含的.h文件。该的* .c档案每个LIB只包括父的* .h文件。的结构类似于一个树

But where should I define it? I have one 'main' *.h-file that is included by all other libs. The *.c-files for each lib include only the 'parent' *.h-file. The structure is similar to a tree:

Main.h
      Main.c
  Child.h
      Child.c
  Child2.h
      Child2.c
  ....

孩子们总是包含 Main.h child.c 他们的父母。但是,在一个库中我得到的错误,该类型是不确定的。

The children always include the Main.h and the child.c their parents. But in one library I get the error, that the type is not defined.

目前,它在Main.h文件声明。但如果是把它放到最好的地方?

At the moment it is declared in the Main.h-file. But where is the best place to put it into?

推荐答案

不管你做什么,你应该从 _C8B10 结构变量改变的东西,不会对保留实施空间践踏。

Namespace conflict

Whatever else you do, you should change the structure tag from _C8B10 to something that does not trample on the namespace reserved to the implementation.

¶1每个标题声明或定义在其相关的上市节所有标识符,并
  可选声明或定义在其相关联的未来图书馆方向上市标识符
  款和它们总是保留要么为任何用途或用作文件识别符
  范围标识符。结果
   - 与下划线和大写字母或其他开头的所有标识符
  下划线,始终保留用于任何用途。结果
   - 以下划线开头的所有标识符总是保留用作标识符
  在这两个普通和标记的名称空间文件范围。

ISO/IEC 9899:2011

7.1.3 Reserved identifiers

¶1 Each header declares or defines all identifiers listed in its associated subclause, and optionally declares or defines identifiers listed in its associated future library directions subclause and identifiers which are always reserved either for any use or for use as file scope identifiers.
— All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use.
— All identifiers that begin with an underscore are always reserved for use as identifiers with file scope in both the ordinary and tag name spaces.

以下划线开头的名称是有风险的;他们在那里的系统库的供应商。显然,如果你的库是实现的一部分,这并不适用于你,但我认为这不太可能,你会问的问题,如果是这样的话。

Names starting with an underscore are risky; they are there for providers of the system libraries. Obviously, if your library is part of the implementation, this doesn't apply to you, but I think it unlikely that you'd be asking the question if that were the case.

如果这是我的code,我只要简单地把下划线: typedef结构C8B10 {...} C8B10; 是罚款(的typedef 的名字都在普通的标识符命名空间,结构变量是在标签的命名空间,且两者并不冲突)。

If it was my code, I'd simply drop the underscore: typedef struct C8B10 { ... } C8B10; is fine (typedef names are in the ordinary identifiers namespace, the structure tag is in the tags namespace, and the two do not conflict).

您图表是从落后的方式大多数人通常写这样的图表。该人士$ ​​C $ C包括报头,所以它可能是图解如下:

Your diagram is backwards from the way most people normally write such diagrams. The source code includes the headers, so it might be diagrammed as:

main.c
    main.h
child1.c
    child1.h
child2.c
    child2.h

然而,这不能成为整个故事。您创建一个标题共享源文件的声明;是仅由一个文件中包含的报头是不严格要求(尽管可存在用于创建这样的文件的合法的原因)。无论是文件的main.c 使用了一些功能(和类型 - 也许宏甚至全局变量,灭亡的思想)的 child1定义。 ç child1.c 的code使用的材料从的main.c (或可能两个)。因此,无论是的main.c 应包括 child1.h child1.c 应包括 main.h 或两者兼而有之。

However, that can't be the whole story. You create a header to share declarations between source files; a header that is included by just one file is not strictly necessary (though there can be legitimate reasons for creating such files). Either the file main.c uses some of the functions (and types — and maybe macros or even global variables, perish the thought) defined in child1.c or the code in child1.c uses the material from main.c (or possibly both). Therefore, either main.c should include child1.h or child1.c should include main.h or both.

这是你需要的库要考虑的另一个方面是如何将库中的客户机使用code?这是至关重要的。将客户端code需要什么头?将客户端code需要什么样的功能?将客户端code所需的任何类型的定义?将在客户端code需要访问C8B10结构的成员,或将他们只需要把它当作一个不透明的类型?

The other aspect that you need to consider with a library is 'how will clients of the library use the code?' This is crucial. What header will the client code need? What functions will the client code need? Will the client code need any type definitions? Will the client code need to access the members of the C8B10 structure, or will they only need to treat it as an opaque type?

您外部头 - 由库的客户端中使用的 - 应该尽可能地小,但自包含的。让我们假设外部头是 c8b10.h 。如果客户端源$ C ​​$ c的的#includec8b10.h作为源文件中的第一个或唯一的头,头中的code应该编译。如果你的接口使用为size_t ,例如,你需要的#include< STDDEF.H>在 c8b10.h

Your external header — the one used by clients of the library — should be as small as possible, but self-contained. Let's assume that the external header is c8b10.h. If the client source code has #include "c8b10.h" as the first or only header in the source file, the code in the header should compile. If your interface uses size_t, for example, you need to #include <stddef.h> in c8b10.h.

在你的情况,我会期望你的 C8B10 结构应在 main.h 定义和两个 child1.c child2.c 应包括 main.h 。它很可能是的main.c 还应该包括 child1.h child2.h 。和 main.h 应该包括外部 c8b10.h 头,所以其实每一个文件包括

In your circumstances, I'd expect that your C8B10 structure should be defined in main.h and both child1.c and child2.c should include main.h. It is likely that main.c should also include both child1.h and child2.h. And main.h should include the external c8b10.h header, so in fact every file includes that.

main.c
    main.h
        c8b10.h
    child1.h
    child2.h
child1.c
    main.h
        c8b10.h
    child1.h
child2.c
    main.h
        c8b10.h
    child2.h

无论 child2.c 需要包括 child1.h 是否 child1.c 需要包括 child2.h 取决于如何code被写入并且每个文件中提供的服务所使用的地方。

Whether child2.c needs to include child1.h and whether child1.c needs to include child2.h depends on how the code is written and which of the services provided by each file are used where.

您可能会发现更明智的只有两个头 - 外部 c8b10.h 头和一个内部的头 c8b10-private.h 。在 c8b10-private.h 头会被库中的每个源文件被包括在内。第一个报头,将包括为外部 c8b10.h 头(自动帮助检查 c8b10.h 头是自包含的)。在 c8b10-private.h 头将对应于 main.h child1合并.H child2.h ,在零下 c8b10.h 定义的外部访问的内容。这导致:

You might find it more sensible to have just two headers — the external c8b10.h header and one internal header c8b10-private.h. The c8b10-private.h header would be included by each source file in the library. The first header it would include is the external c8b10.h header (to help automatically check that the c8b10.h header is self-contained). The c8b10-private.h header would correspond to the merger of main.h, child1.h and child2.h, minus the externally accessible content defined in c8b10.h. This leads to:

main.c
    c8b10-private.h
        c8b10.h
child1.c
    c8b10-private.h
        c8b10.h
child2.c
    c8b10-private.h
        c8b10.h

的关键点要记住的是,标题是源文件之间的通信。其余的从很大程度上自动跟随。

The key point to remember is that headers are for communicating between source files. The rest follows largely automatically from that.

这篇关于定义一个结构为图书馆最好的地方的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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