неустраненные внешние ошибки

У меня есть следующие файлы .h и .cpp

Если мне нужно, я включу полные коды определений функций.

Когда я компилирую свою программу, я получаю ошибки, показанные в конце

хэш.ч

    #define BUCKETS 64
       #define B_ENTRIES 50000
       int curr_tanker;
       typedef unsigned long int ulong;
typedef struct bucket
{
    int bucket_id;
    ulong bucket_entries;
}bucket;

typedef struct tanker_record
{
    ulong tanker_id;
    ulong tanker_size;
    ulong num_of_entries;
    ulong bucket_entry_count;
   }tanker_record;
typedef struct fpinfo
{ 
    unsigned long chunk_offset;
    unsigned long chunk_length;
    unsigned char fing_print[33];

}fpinfo;

struct fpinfo* InitHTable(fpinfo *);
int CreateTanker(tanker_record tr[]);
int Hash_CreateEntry(struct fpinfo *,struct fpinfo he,tanker_record tr);

ht.cpp

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

#include "ht.h"

struct fpinfo* InitHTable(struct fpinfo ht[][B_ENTRIES])
{
}
int CreateTanker(tanker_record tr[])
{
}
int
Hash_CreateEntry(struct fpinfo *t[][B_ENTRIES],struct fpinfo he,tanker_record tr[])
{
}
static void
WriteHTtoFile(struct fpinfo *t[][B_ENTRIES],int this_tanker)
{
}

main.cpp

#include<iostream>
#include"ht.cpp"
#include<conio.h>
#include<stdlib.h>

void main(int argc, char **argv)
{
static fpinfo hash_table[BUCKETS][B_ENTRIES];
static tanker_record tr[100];
InitHTable(&hash_table[0][0]);
CreateTanker(tr);
struct fpinfo fp;
... 
ar = Hash_CreateEntry(&hash_table[0][0], fp,tr[0]);

я получаю следующие ошибки, когда пытаюсь скомпилировать его с помощью vc2010

1> main.obj: ошибка LNK2005: «struct fpinfo * __cdecl InitHTable (struct fpinfo (* const) [50000])» (?InitHTable@@YAPAUfpinfo@@QAY0MDFA@U1@@Z), уже определенная в ht.obj

1>main.obj: ошибка LNK2005: «int __cdecl CreateTanker (struct tanker_record * const)» (?CreateTanker@@YAHQAUtanker_record@@@Z), уже определенный в ht.obj

1> main.obj: ошибка LNK2005: «int __cdecl Hash_CreateEntry (struct fpinfo * (* const) [50000], struct fpinfo, struct tanker_record * const)» (?Hash_CreateEntry@@YAHQAY0MDFA@PAUfpinfo@@U1@QAUtanker_record@@@ Z) уже определено в ht.obj 1>main.obj : ошибка LNK2005: "int curr_tanker" (?curr_tanker@@3HA) уже определено в ht.obj 1>main.obj : ошибка LNK2019: неразрешенный внешний символ "int __cdecl Hash_CreateEntry (struct fpinfo *,struct fpinfo,struct tanker_record)" (?Hash_CreateEntry@@YAHPAUfpinfo@@U1@Utanker_record@@@Z) упоминается в функции _main 1>main.obj : ошибка LNK2019: неразрешенный внешний символ "struct fpinfo * __cdecl InitHTable (struct fpinfo *)" (?InitHTable@@YAPAUfpinfo@@PAU1@@Z), указанный в функции _main

СПАСИБО ЗА ВАШУ ПОМОЩЬ!!


person John    schedule 27.02.2012    source источник


Ответы (2)


Вы включаете ht.cpp из main.cpp, что будет включать все определения функций, уже определенных в самом ht.cpp.

Вместо этого вы хотите включить ht.h.

В данной ситуации это не поможет, но вы также должны защитить заголовочный файл с помощью include guards:

#ifndef HT_H
#define HT_H

// contents of ht.h

#endif

Вам также нужны аргументы объявлений функций, чтобы они соответствовали аргументам определений:

struct fpinfo* InitHTable(struct fpinfo[][B_ENTRIES]);
// Missing:                              ^^^^^^^^^^^

int CreateTanker(tanker_record tr[]); // OK

int Hash_CreateEntry(struct fpinfo*[][B_ENTRIES],struct fpinfo,tanker_record[]);
// Missing                         ^^^^^^^^^^^^^                            ^^
person Mike Seymour    schedule 27.02.2012
comment
это было то, что я сделал изначально, но все равно выдает последние три ошибки. Это позволяет избежать только первых двух ошибок lnk2005. - person John; 27.02.2012
comment
@John: О да, мои глаза, должно быть, остекленели, когда я прочитал ошибки. Это потому, что объявления не соответствуют определениям — объявления имеют аргументы указателя на объект, а определения имеют аргументы указатель на массив. - person Mike Seymour; 27.02.2012
comment
Спасибо. Но какой правильный синтаксис для вызовов функций? Первые создают ошибки ошибка C2664: 'InitHTable' : невозможно преобразовать параметр 1 из 'fpinfo *' в 'fpinfo *[][50000]' и ошибка C2664: 'Hash_CreateEntry' : невозможно преобразовать параметр 1 из 'fpinfo *' в 'fpinfo *[][50000]' - person John; 27.02.2012
comment
@John: Похоже, это должно быть что-то вроде Hash_CreateEntry(hash_table,fp,tr);. Хотя трудно быть уверенным; дополнительный * в определении функции, по-видимому, подразумевает, что hash_table должен быть двумерным массивом указателей, а не объектов. - person Mike Seymour; 27.02.2012
comment
у меня другая проблема. Он говорит, что функция WriteHTtoFile() объявлена, но не определена, в чем может быть проблема? Я предполагаю, что это какое-то несоответствие типа аргумента, но как бы я ни смотрел на это, я не мог понять это. - person John; 27.02.2012
comment
@John: я думаю, это вызывается из одной из других функций в этом файле. Функции должны быть объявлены (или определены) до того, как они будут вызваны — либо переместите определение этого файла выше других функций, либо поместите объявление над ними. - person Mike Seymour; 27.02.2012

Добавьте в заголовок «включить защиту», чтобы его содержимое не «просматривалось» дважды после предварительной обработки. Для Microsoft: #pragma once в начале файла .h. В общем добавьте:

#ifndef __YOUR_HEADER_H
#define __YOUR_HEADER_H
// all the stuff from the header here
#endif

Обязательно используйте согласованную «уникальную» схему именования для каждого из ваших заголовков. __YOUR_HEADER_H подойдет, например customio.h в __CUSTOM_IO_H.

person foxx1337    schedule 27.02.2012
comment
Хорошая идея, но вы не должны использовать зарезервированное имя, если это происходит. - person Mike Seymour; 27.02.2012
comment
Когда я сделал, как вы сказали, я получаю ошибку C2337: 'имя_переменной': атрибут не найден для всех переменных, используемых в ht.cpp - person John; 27.02.2012
comment
Это потому, что вы определяете хранилище в своем заголовке. Заголовки должны быть только для объявлений, максимум для констант. Всегда объявляйте хранилище — поместите extern int curr_tanker; в заголовок и поместите правильный int curr_tanker; в файл реализации .cpp. - person foxx1337; 27.02.2012