简介
我是一名经验丰富的程序员,在面向对象范式方面拥有多年经验。最近我决定尝试更熟悉和熟悉比 C# 或 Java 等更低级别的语言,所以我正在研究 C,并将尝试创建一些游戏与它。
一切都很顺利,现在我正试图通过将函数定义移动到单独的 .c 文件中来更好地组织我的代码。由于 C 中包含的性质,这是我开始感到不舒服的地方。我很熟悉它是如何工作的,也很熟悉编译过程中的预处理阶段。问题是我仍然不确定我是否正确处理了这个问题。
我认为我的问题类似于所问的问题 here .虽然它不能完全满足我需要知道的内容。
问题
基本上,我正在使用两个库创建一个 OpenGL 项目。一个是 glew(用于 OpenGL 函数加载),另一个是 GLFW(用于窗口处理和 OpenGL 上下文创建)。我有两个 .c 文件,一个名为 main.c,另一个名为 windowInitialize.c。问题是,main.c 和 windowInitialize.c 都依赖于 glew 和 glfw 库。
在我的 main.c 文件中,我执行以下操作:
#include "includes/GLEW/glew.h"
#include "includes/GLFW/glfw3.h"
#include "windowInitialize.h"
此外,main.c还进行了以下相关函数调用:
if (!initializeGLFW())
return -1;
GLFWwindow *window = createOpenGLWindow(3, 3, 640, 480, "Hello OpenGL");
/* It is important that we initialize glew AFTER initializing GLFW and setting up
the OpenGL context, as GLEW needs a current context to work */
initializeGLEW();
windowInitialize.c 包括函数 initializeGLFW 和 initializeGLEW 以及 createOpenGLWindow 的定义。 main.c 源代码仍然使用 glew 和 glfw 作为主循环目的,引用两者的函数等。
现在,windowInitialize.c 包括:
#include "windowInitialize.h"
#include "includes/GLEW/glew.h"
#include "includes/GLFW/glfw3.h"
#include <stdio.h>
然后继续填写函数定义。所以这就是交易。这两个文件都需要使用 glew 和 glfw 库,实际上还有 stdio(用于打印调试消息等)。
我觉得这不是正确的做法,但我不确定。我相信编译器/链接器没有提示双重声明的原因是因为 main.c 和 windowInitialize.c 获取单独的目标代码文件。
但我的问题是,链接器是否足够聪明,只将这些声明放在可执行文件中一次?所以即使我在几个地方包含这些标题,它也不会对文件大小等产生任何影响?这甚至是处理多个源文件之间共同依赖关系的正确方法吗?或者我应该使用其他方法?
最佳答案
您所描述的一切似乎都是正常的做事方式。您的两个编译单元只会在这些 header 中获得相同的前向声明函数,而不是来自库的实际重复定义。
My question is though, is the linker clever enough to only put these declarations in the executable file once?
链接器当然不关心您包含什么头文件 - 它是链接器,而不是编译器。
So that even though I include these headers several places, it won't have any effect on file size and such?
函数的额外/未使用前向声明不会影响二进制大小。
And is this even the correct way of handling common dependencies between several source files?
是的,你似乎以完全正常的方式做事。
对于您的项目,您应该这样做:
cc -c -o main.o main.c # compile main.c
cc -c -o windowInitialize.o windowInitialize.c # compile windowInitialize.c
cc -o myProgram main.o windowInitialize.o -lglew -lglfw # link objects with necessary libraries to create executable
但是,实际上,使用 makefile 会更好:
myProgram: main.o windowInitialize.o
cc -o $@ $^ -lglew -lglfw
使用示例:
$ make
cc -c -o main.o main.c
cc -c -o windowInitialize.o windowInitialize.c
cc -o myProgram main.o windowInitialize.o -lglew -lglfw
关于c - 需要一些关于 C header 包含的建议,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17981565/