0

我正在使用这个头文件来读取文本文件(我用它来加载着色器文件)并且我在两个不同的类中使用它。

我收到 textFileRead(char*) 的多重定义错误。

这是头文件:

#ifndef READFILE_H
#define READFILE_H

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "string"
#include "fstream"

char *textFileRead(char *fn) {

FILE *fp;
char *content = NULL;

int count=0;

if (fn != NULL) {
    fp = fopen(fn,"rt");

    if (fp != NULL) {

  fseek(fp, 0, SEEK_END);
  count = ftell(fp);
  rewind(fp);

        if (count > 0) {
            content = (char *)malloc(sizeof(char) * (count+1));
            count = fread(content,sizeof(char),count,fp);
            content[count] = '\0';
        }
        fclose(fp);
    }
}
return content;
}


#endif READFILE_H

我究竟做错了什么?

4

3 回答 3

0

您需要确保每个编译单元只包含一次头文件中的代码。为此,您将其放在文件的开头:

#ifndef READFILE_H
#define READFILE_H

最后是:

#endif

当然,每个文件的标识符 READFILE_H 应该是唯一的。接下来要做的是:只在头文件中保留函数和类的声明,实现应该存在于单独的实现文件(.c 或 .cpp 或 .cc)中。因此,在您的标题中,您将仅声明您的函数:

char *textFileRead(char *);

并且您的函数的定义将在一个单独的 .c 文件中。

于 2012-11-25T18:04:35.030 回答
0

头文件中定义的函数需要标记为inline防止多重定义。

要么这样,要么将实现分离到实现文件中。

Include guards 防止在同一个翻译单元中出现多个定义,这是一个链接器问题。该符号在翻译单元中被多次定义。

于 2012-11-25T18:20:10.317 回答
0

您在头文件中定义函数,这意味着编译器将在包含此头文件的每个源文件中复制相同的函数。在链接目标文件时,链接器将不知道要使用哪个版本。(它不能知道它们是一样的,只是它们的签名是一样的。)

解决此问题的一种方法是将实现移动到源文件,并将声明保留在头文件中,如下所示:

读取文件.h

#ifndef READFILE_H
#define READFILE_H

char *textFileRead(char *fn);

#endif

读取文件.cpp

#include "readfile.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <fstream>

char *textFileRead(char *fn) 
{
    FILE *fp;
    char *content = NULL;
    int count=0;

    /* ... code ... */

    return content;
}

另一种解决方案是标记函数inline并将实现留在头文件中。像这样:

#ifndef READFILE_H
#define READFILE_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <fstream>

inline char *textFileRead(char *fn) 
{
    FILE *fp;
    char *content = NULL;

    /* ... code ... */

    return content;
}

在最后一种情况下,编译器可能会选择在调用它的地方内联函数,而不是生成对它的调用。

也可以在上面的示例中使用static代替inline,或者将定义包围在匿名命名空间中。但是,这两种方法都不推荐。除非您有特定的原因想要潜在地内联您的函数并使其主体在头文件中可用,否则我会选择第一个替代方案。

于 2012-11-25T18:22:40.530 回答