Code::Blocks 中的头文件和源文件问题

Posted

技术标签:

【中文标题】Code::Blocks 中的头文件和源文件问题【英文标题】:Header and Source file problems in Code::Blocks 【发布时间】:2016-01-17 19:29:11 【问题描述】:

我正在使用 Code::Blocks 用 C 语言编写游戏。我正在使用最新版本的 C 和 Code::Blocks。我还在学习这门语言。

我过去的所有程序都包含在一个巨大的源文件中,因此我决定分支并尝试将我的代码放在多个文件中。我知道这样做的正确方法是拥有包含代码定义等的源文件和一个包含原型的头文件,以供其他源文件使用。这对我来说非常糟糕,我要么无法使文件正常工作,要么就是无法正常工作。

我在一个名为process.c 的源文件中有一个函数,在一个名为process.h 的文件中有一个函数原型。我还有一个 main.h 和一个 main.c 包含所有其余代码。主要问题是我的main.h 文件中有一个typedef struct Game,我无法获得我创建的'Game' 结构类型以在我的process.c 中工作。我游戏中的每个功能都需要Game 类型才能工作。但是,当我让process.c 访问main.h(声明Game 的文件)时,我遇到了问题。

我的代码在一个文件中时可以正常工作。我的头文件受到保护,不会重复,并且正确地包含在程序中。问题是,我需要在main.cprocess.c 中都包含main.h。我必须在'main.c'和'process.c'中都包含process.h。我已经尝试了所有配置,但没有任何效果。

在某些 #include 配置中,我没有收到任何错误,但我收到一条奇怪的消息,上面写着“您的项目似乎尚未构建;您想现在构建它吗?”当我点击“是”时,什么也没有发生。

我的编译器工作正常,项目设置没有任何问题。这到底是怎么回事?如何让main.hprocess.h 一起工作?

编辑:源代码:

main.c:

#include <stdio.h>
#include "main.h"
#include "process.h"

void initGame(Game *thisGame)

  variable = 10;
  number = 5;
  letter = 'c';


int main()

Game thisGame;
initGame(&thisGame);
displayData(&thisGame);
return 0;

main.h:

#ifndef _MAIN_H_ 
#define _MAIN_H_

typedef struct

int variable, number;
char letter;


#endif

process.c:

#include <stdio.h> //not sure if this should be here or not, it doesn't seem to effect my code
#include "main.h"
#include "process.h"

void displayData(Game *thisGame)

printf("%i, %i, %c", thisGame.variable, thisGame.number, thisGame.letter);

进程.h:

#ifndef _MAIN_H_ 
#define _MAIN_H_

void displayData(Game *thisGame);

#endif

错误信息

-------------- Build: Debug in FishKiller (compiler: GNU GCC Compiler)---------------

mingw32-g++.exe -L..\deps\lib -L..\SDLFILES\lib -o bin\Debug\FishKiller.exe obj\Debug\main.o obj\Debug\process.o  -lmingw32 -lSDL2main -lSDL2  -lSDL2_image  
obj\Debug\process.o:process.c:(.rdata+0x0): multiple definition of `SCREEN_WIDTH'
obj\Debug\main.o:main.c:(.rdata+0x0): first defined here
obj\Debug\process.o:process.c:(.rdata+0x4): multiple definition of `SCREEN_HEIGHT'
obj\Debug\main.o:main.c:(.rdata+0x4): first defined here
obj\Debug\process.o:process.c:(.rdata+0x8): multiple definition of `GAMESTATE_MENU'
obj\Debug\main.o:main.c:(.rdata+0x8): first defined here
obj\Debug\process.o:process.c:(.rdata+0xc): multiple definition of `GAMESTATE_GAME'
obj\Debug\main.o:main.c:(.rdata+0xc): first defined here
obj\Debug\process.o:process.c:(.rdata+0x10): multiple definition of `GAMESTATE_GAMEOVER'
obj\Debug\main.o:main.c:(.rdata+0x10): first defined here
collect2.exe: error: ld returned 1 exit status
Process terminated with status 1 (0 minute(s), 0 second(s))
0 error(s), 0 warning(s) (0 minute(s), 0 second(s))

【问题讨论】:

从您所描述的情况来看,您似乎没有可见性问题。你有基本的使用开发环境问题。从基础开始:你能得到一个简单的 hello world 程序吗? int main(void)printf("hello world!");return 0; 你表示你正在使用 Code::Blocks。你用的是什么编译器?您是在构建控制台应用程序、库……什么? 是的,hello world 程序运行良好。 GCC 编译器。如果我不使用 process.c 文件并在 process.h 文件中定义函数,我可以让程序运行。 我使用您在答案中提供的源代码编辑了您的帖子。通常,原始帖子是此类内容所属的地方。我还针对我在您的源代码中看到的问题创建了一个逐个文件 cmets 的答案。 请注意,错误消息似乎是指变量而不是函数。您在标头中声明变量,前面带有extern。您在一个源文件中定义变量,该文件还包括用于交叉检查的标题。就个人而言,我在标头中声明函数时在前面加上extern,以便与那些必须声明的罕见全局变量对称——许多(可能是大多数)人不同意我的观点。 好消息:我让它工作了。我所要做的就是将我在 mina.h 文件中声明的三个常量整数更改为 #define 常量。感谢 Jonathen Leffler 和 ryyker 帮助我解决这个问题,我很惊讶我能在这个网站上找到我需要的答案。 【参考方案1】:

问题是以下逐个文件的地址。在您的源代码中更正这些问题后,可执行文件将构建。

1) 在 process.h 你有错误的标题块:

#ifndef _MAIN_H_ 
#define _MAIN_H_
//Change to:
#ifndef _PROCESS_H_ 
#define _PROCESS_H_

也改变:

void displayData(Game *thisGame);(see notes in main.h for explanation)

收件人:

void displayData(GAME *thisGame);

2) 在 process.c 你有;

#include "main.h"

这并没有什么坏处,但是由于我们正在分析所有内容,因此不需要它来支持当前架构。

你还有:

printf("%i, %i, %c", thisGame.variable, thisGame.number, thisGame.letter);

因为thisGame是作为指针传入的,所以需要使用struct指针运算符:-&gt;

printf("%i, %i, %c", thisGame->variable, thisGame->number, thisGame->letter);

另外,同一文件中的函数协议不正确。您正在尝试实例化一个不存在的变量类型:(请参阅 main.h 的注释) 变化:

void displayData(Game *thisGame)...

收件人:

void displayData(GAME *thisGame)...//uses typedef struct GAME 

3) 在 main.h 你有一个格式错误的结构:

typedef struct

    int variable, number;
    char letter;
//no ";" statement terminator to indicate to your compiler _end of struct_

有了这个定义,没有结构 name 可以在任何其他文件中引用或实例化它。将其更改为以下内容:

typedef struct

    int variable;
    int number;//style point , put each member on its own line
    char letter;
GAME;//note struct type name and terminator ";"

使用结构类型名称,在本例中为 GAME,您可以在 #includes 此文件的任何文件中创建此结构的实例。

extern GAME Game;// using the extern modifier, create an instance of GAME  
                 // that can be referenced in any file of the
                 //project, once initialized.  (See the line GAME Game; in main.c)

4) 在 main.c 中,您在函数 initGame 中有需要以不同方式引用的变量。改变这个:

void initGame(Game *thisGame)

  variable = 10;
  number = 5;
  letter = 'c';

收件人:

void initGame(GAME *thisGame)

  thisGame->variable = 10;
  thisGame->number = 5;
  thisGame->letter = 'c';

Code::Blocks information here 可以帮助您设置环境以获取有助于调试代码的错误消息。

【讨论】:

以上是关于Code::Blocks 中的头文件和源文件问题的主要内容,如果未能解决你的问题,请参考以下文章

如何在Code::Blocks中查看打开的文件或项目中的函数列表?

我想问一下vs 2008中的头文件的问题啊

Code::Blocks

code blocks主题颜色配置

windows 环境下编译 Code::Blocks

Code::Blocks 在“递归添加文件”到空项目后崩溃