textFileRead(char*)的多重定义

Multiple Definition of textFileRead(char*)

本文关键字:定义 char textFileRead      更新时间:2023-10-16

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

我得到错误的多重定义的文本文件读取(字符*)。

这是头文件:

#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] = '';
}
fclose(fp);
}
}
return content;
}

#endif READFILE_H

我做错了什么?

表头定义的函数需要标记为inline,以防止多重定义。

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

在同一翻译单元中包含防止多个定义的保护,这是一个链接器问题。符号在翻译单位中定义多次。

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

#ifndef READFILE_H
#define READFILE_H

最后这个:

#endif

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

char *textFileRead(char *);

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

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

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

readfile.h

#ifndef READFILE_H
#define READFILE_H
char *textFileRead(char *fn);
#endif

readfile.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,或者将定义包围在匿名命名空间中。然而,这两种方法都不推荐使用。除非您有特定的原因想要潜在地内联您的函数并使其正文在头文件中可用,否则我会选择第一种选择。

相关文章: