(.bss + 0x0): множественное определение «player»;

Я создаю игру в Ray lib, и у меня есть файл заголовка игрока со структурой player, чтобы все было организовано. Я получаю эту ошибку, говоря, что существует несколько определений структуры player.

Ошибка:

/usr/bin/ld: main.o:(.bss+0x0): multiple definition of `player'; player.o:(.bss+0x0): first defined here collect2: error: ld returned 1 exit status

player.cpp:

#include <raylib.h>
#include "player.h"

void InitPlayer() {

    player.x = 0;
    player.y = 0;

    player.tint = (Color)RAYWHITE;
    player.Frame = 0;
    player.FrameWidth = 16;
    player.MaxFrames = 3;
    player.animation_number = 0;
    player.timer = 0.0f;    

    player.flip = 1;

    //Load Texture2D
    player.playerTexture = LoadTexture("Sprites/PlayerAll.png");

}

void UpdatePlayer() {

player.timer += GetFrameTime();
    
if(player.timer >= 0.2f){
    
        player.timer = 0.0f;
        player.Frame += 1;  
}

if(IsKeyDown(KEY_S)) {
        player.animation_number = 16;   
        player.y += 1;  
    }else if(IsKeyUp(KEY_S)){
        player.animation_number = 0;
    }
    
    
    if(IsKeyDown(KEY_W)){
        player.animation_number = 32;
        player.y -= 1;
    }
    
    if(IsKeyDown(KEY_A)){
        player.animation_number = 48;
        player.x -= 1;'''
    }
        
    if(IsKeyDown(KEY_D)){
        player.animation_number = 48;
        player.x += 1;
        player.flip = -1;
    } else {
        player.flip = 1;
    }
    
    //Clamp frame value
    player.Frame = player.Frame % player.MaxFrames;

}

void DrawPlayer() {
    
DrawTexturePro(player.playerTexture,
        Rectangle{player.FrameWidth*player.Frame,(float)player.animation_number,(float)player.flip*16,16},
        Rectangle{(float)player.x,(float)player.y,16,16},
        Vector2{0,0},0,player.tint);
}

void UnloadPlayer() {
    
    UnloadTexture(player.playerTexture);
}

Player.cpp:

#ifndef PLAYER_H
#define PLAYER_H

typedef struct Player{
    
    int x, y;
    Color tint; 

    int Frame;
    int FrameWidth;
    int MaxFrames;
    int animation_number;   
    float timer;    

    int flip;   
    Texture2D playerTexture;
        
}Player;

Player player;


void UnloadPlayer();
void InitPlayer();
void UpdatePlayer();
void DrawPlayer();
#endif

Main: файл main.cpp в основном вызывает функции из файла player.h. И я включил player.h в main.cpp

Просто для дополнительной информации, если это необходимо: я пробовал использовать extern в проигрывателе, но это требует, чтобы я скомпилировал файлы cpp в странном порядке. После компиляции и связывания обоих объектов player.o и main.o я заменяю player.cpp на extern в глобальной переменной структуры player и компилирую player.cpp только без компиляции main. cpp 'и свяжите оба файла объектов со старым файлом main.o.


person Shahroz    schedule 06.11.2020    source источник
comment
Почему вы делаете такой странный способ компиляции? Вместо этого попробуйте правильно объявить глобальный player в player.cpp или main.cpp - только в одном или другом, а не в обоих. Вы действительно должны показать нам минимальный пример, включая минимальный player.cpp - не могу точно сказать, что происходит, без объявления глобальной переменной. (Примечание: если вам нужно отредактировать исходный код и перекомпилировать файл, чтобы связать ссылку, вы уже делаете что-то не так, чтобы требовать этого.)   -  person davidbak    schedule 06.11.2020
comment
P.S. Ваше определение struct Player ужасно похоже на C. Это не должно повредить так, просто просто объявите это прямо в стиле C ++: struct Player { ... };.   -  person davidbak    schedule 06.11.2020
comment
Секунду назад я думал, что видел extern перед Player player в шапке? Не там сейчас? Должен быть.   -  person davidbak    schedule 06.11.2020
comment
Глобальные объекты? Глобальные функции для работы с этим глобальным объектом? Не очень C ++. Получите несколько хороших книг, чтобы правильно изучить C ++ , в том числе о том, как использовать классы и функции-члены.   -  person Some programmer dude    schedule 06.11.2020
comment
@davidbak Мне очень жаль, что я неправильно истолковал то, что я сделал, как глобальную переменную. «Player» объявлен в заголовочном файле как «Player player;».   -  person Shahroz    schedule 07.11.2020
comment
Заголовочный файл включен в несколько исходных файлов. Следовательно, каждый глобальный объект, объявленный в заголовке, должен быть объявлен extern. Затем вы выбираете один исходный файл и объявляете его там без extern. Это станет реальным экземпляром - единственным экземпляром - этого глобального в вашей программе. extern (в заголовке) говорит, что глобальный будет где-то существовать, но фактически не объявляет его. Если глобальный объект в заголовке не имеет extern, тогда он будет существовать в каждом исходном файле, который его включает: это множественное определение одного и того же объекта и не допускается.   -  person davidbak    schedule 07.11.2020
comment
@davidbak Отличное объяснение, спасибо, сработало.   -  person Shahroz    schedule 07.11.2020