0

このヘッダー ファイルを使用してテキスト ファイルを読み取り (シェーダー ファイルを読み込むために使用します)、2 つの異なるクラスで使用します。

複数の定義の 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

inlineヘッダーで定義された関数は、複数の定義を防ぐためにマークする必要があります。

これか、実装を実装ファイルに分離します。

インクルード ガードは、同じ翻訳単位での複数の定義に対するガードです。これはリンカの問題です。シンボルは、翻訳単位全体で複数回定義されています。

于 2012-11-25T18:20:10.317 に答える
0

ヘッダー ファイルで関数を定義しています。つまり、コンパイラは、このヘッダーをインクルードする各ソース ファイルに同じ関数のコピーを作成します。オブジェクト ファイルのリンクに関しては、リンカは使用するバージョンを認識できません。(署名が同じであるというだけで、それらが同じであることを知ることはできません。)

これを修正する 1 つの方法は、次のように、実装をソース ファイルに移動し、宣言をヘッダー ファイルに残すことです。

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;
}

もう 1 つの解決策は、関数をマークして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 に答える
0

ヘッダー ファイルのコードがコンパイル ユニットごとに 1 回だけインクルードされるようにする必要があります。これを行うには、これをファイルの先頭に置きます。

#ifndef READFILE_H
#define READFILE_H

そして最後にこれ:

#endif

もちろん、識別子 READFILE_H はファイルごとに一意である必要があります。次に行うことは、関数とクラスの宣言のみをヘッダーに残し、実装は別の実装ファイル (.c または .cpp または .cc) に置くことです。したがって、ヘッダーには関数のみの宣言があります。

char *textFileRead(char *);

関数の定義は別の .c ファイルになります。

于 2012-11-25T18:04:35.030 に答える