【问题标题】:How do I write a proper include and modulize my app in C?如何在 C 中编写正确的包含和模块化我的应用程序?
【发布时间】:2020-02-24 18:51:22
【问题描述】:

我再次寻求您的帮助 :) 在#includes 中找不到错误,检查了几次,与 geekstogeeks 示例和此处的类似问题进行了比较。所以我有:

/tmp/ccWUaJkV.o:/home/felix/Programming/dypak/objects.obj:27: multiple definition of `RankNames'
/tmp/ccA7hhxl.o:/home/felix/Programming/dypak/objects.obj:27: first defined here
/tmp/ccWUaJkV.o:/home/felix/Programming/dypak/objects.obj:28: multiple definition of `SuitNames'
/tmp/ccA7hhxl.o:/home/felix/Programming/dypak/objects.obj:28: first defined here
/tmp/ccWUaJkV.o:(.bss+0x0): multiple definition of `__odr_asan.SuitNames'
/tmp/ccA7hhxl.o:(.bss+0x0): first defined here
/tmp/ccWUaJkV.o:(.bss+0x1): multiple definition of `__odr_asan.RankNames'
/tmp/ccA7hhxl.o:(.bss+0x1): first defined here
collect2: error: ld returned 1 exit status


编译后

gcc -rdynamic -std=c11 `pkg-config --cflags gtk+-3.0` cardmethods.c main.c -o main `pkg-config --libs gtk+-3.0` -lX11

objects.obj

#include <stdbool.h>
#ifndef OBJECTS_O_
#define OBJECTS_O_

typedef struct myCard{
    bool trump;
    ...
} card;
typedef struct {
     ...
} widgetsPtrs;

card *Deck;//pointer to the deck.
/************************************HERE****************************/
char *RankNames[] = {"  6  ", "  7  ", "  8 ", ...};
char *SuitNames[] = {"Hearts", "Spades", "Diamonds", "Clubs"};

#endif

cardmethods.h

#include <stdbool.h>
#include <gtk/gtk.h>
#include "objects.obj"

#ifndef CARDMETHODS_H_
#define CARDMETHODS_H_

void addCard(card *pile, card *cardAdded);
void printAll(card *pile);
...


#endif

cardmethods.c

#include "cardmethods.h"
#include <time.h>
#include <stdio.h>
#include <stdlib.h>

void addCard(card *pile, card *cardAdded){
    ...
}
void printAll(card *pile){
    ...
}
...

main.c

#include <gtk/gtk.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <time.h>
#include "cardmethods.h"

 ...

int main (int    argc,
      char **argv)
{
  ...
  return 0;
}

【问题讨论】:

  • 您不能全局定义RankNamesSuitNames 相乘。如果您想将它们用作某种常量,您可以声明它们static 以限制对当前翻译单元的可见性并避免多个定义错误。那么你也应该声明它们const
  • 请注意,名称objects.obj 将是 Windows 系统上的目标文件。选择一个不同的后缀,为了他人的理智,即使不是为了你自己。
  • 当你使用包含守卫时,它们在标题中的第一个和最后一个是至关重要的。其他#include 行可能跟在包含守卫之后;他们不应该在他们之前。如果您不遵循此规则,您可能会遇到相互递归的标头问题。

标签: c include c-preprocessor


【解决方案1】:

您已经在头文件中定义了变量RankNamesSuitNames。因此,它们在 main.c 和 cardmethods.c 中都有定义。然后当这些文件被链接时,链接器会找到多个定义。

将头文件更改为具有这些变量的外部声明(和Deck):

extern card *Deck;
extern char *RankNames[];
extern char *SuitNames[];

并将定义放在一个源文件中,可能是cardmethods.c:

card *Deck;
char *RankNames[] = {"  6  ", "  7  ", "  8 ", ...};
char *SuitNames[] = {"Hearts", "Spades", "Diamonds", "Clubs"};

【讨论】:

  • 非常感谢,它运行良好。问题是我重新定义了变量。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-10-12
  • 2018-03-19
  • 2011-09-16
  • 1970-01-01
  • 2012-03-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多