我想在na单个静态C程序中包含一堆数据(比如图像,还有其他数据,嵌入在可执行文件中,因为我在没有文件的嵌入式平台上工作).
因此,我写了一些img2c从我的数据文件中创建const数据,创建一个带有静态const数组初始化器的文件放到flash中(使用C99很棒的功能)
我的问题是,我应该将它们放在.h文件中,就像我多次看到的那样 - 例如gimp可以保存为.h文件,而不是.c文件 - 或者在.c文件中,仅在标题中引用const extern声明进一步引用,不必包含所有数据并将其全部传递给编译器,并在每次使用它时重新声明它?
预处理器宏是不可能的,因为我将引用它们的地址,而不是每次都包含整个数据.
如果将数据放入标头中,则提取该标头的每个编译单元都将获得自己的数据副本。想象一下两个 .c 文件,每个文件都指向一个 .o。每个 .o 都会有一个数据副本,并且您的最终可执行文件可能比它需要的更大。
如果将其放在 .c 中并将其 extern 放在标头中,则只有一个 .o 将包含数据,并且最终的可执行文件会更小。另外,如果您进行更改,如果只是更改单个 .c 而不是包含标头的所有 .c 文件,则重新编译会更快。
正如您所指出的,您还可能会遇到链接器问题,因为符号将被定义多次,请参阅在多个 cpps 中包含相同标头的重复多重定义错误的答案。将 extern 放在标头中并将数据放在 .c 中会更好
C 中的头文件没什么特别的;扩展.h
不会改变编译器处理它们的方式。这更多的是对人类的暗示“这个文件可能不包含任何代码”。
因此,如果您将实际的二进制数据放入其中,编译器将在包含标头的每个文件中创建数组的副本(而不是简单地添加对共享全局数组的引用)。
GIMP 创建一个头文件,因为它不知道您打算如何使用数据。这个想法是,您将在文件中仅包含一次此头文件,.c
然后该文件以某种方式处理数据。如果它写入了一个.c
文件并且您对代码进行了更改,那么当您要求 GIMP 更新数据时,GIMP 必须合并这些更改 - 这会很混乱。