0

I am creating a game in ray lib and have a player header file with a struct of player to keep things organised. I get this error saying that there is multiple definition of the struct 'player'.

Error:

/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: The main.cpp' file basically calls the functions from the 'player.h' file. And I have included 'player.h' in 'main.cpp'

Just for some extra information if needed: I have tried using 'extern' on 'player' but it requires me to compile the cpp files in a strange order. After compiling and linking both object 'player.o' and 'main.o', I change 'player.cpp' to have 'extern' on struct global variable 'player' and compile 'player.cpp' only without compiling 'main.cpp' and link both objects files with the 'main.o' being the old one.

Shahroz
  • 49
  • 9
  • Why are you doing that strange way of compiling? Instead of that try declaring the global `player` properly in either player.cpp or main.cpp - just one or the other, not both. You really should show us a minimal example including a minimal player.cpp - can't really tell what's going on without the declaration of the global variable. (Note: if you have to edit your source and recompile a file in order to link you're doing something wrong already to require that.) – davidbak Nov 06 '20 at 18:13
  • 1
    P.S. you definition of the struct `Player` is awfully C-like. Shouldn't hurt that way, but instead just declare it directly in the C++ style: `struct Player { ... };`. – davidbak Nov 06 '20 at 18:16
  • I thought a second ago I saw an `extern` in front of `Player player` in the header? Not there now? It should be. – davidbak Nov 06 '20 at 18:17
  • Global objects? Global functions to work on that global object? Not very C++. Please get [a few good books](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list/388282#388282) to learn C++ "properly", including how to use classes and member functions. – Some programmer dude Nov 06 '20 at 18:18
  • @davidbak I'm sorry I may have misinterpreted what I did as global variable. The 'player' is declared in the header file as 'Player player;'. – Shahroz Nov 07 '20 at 02:37
  • 1
    The header file is included in multiple source files. Therefore every global declared in a header must be declared `extern`. Then you pick _one_ source file and declare it there _without_ the `extern`. That'll become the real instance - the _only_ instance - of that global in your program. The `extern` (in the header) says the global _will exist somewhere_ without actually declaring it. If the global in the header does _not_ have `extern` then it will exist in _each_ source file that includes it: that's multiple definition of the same thing and not allowed. – davidbak Nov 07 '20 at 05:58
  • @davidbak Great explanation, thank you it worked. – Shahroz Nov 07 '20 at 17:06

0 Answers0