Jump to content

  • Log In with Google      Sign In   
  • Create Account

multiply defined symbols found


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
5 replies to this topic

#1 ChainedHollow   Members   -  Reputation: 158

Like
0Likes
Like

Posted 19 December 2012 - 04:46 AM

I'm doing my first project with multiple files and I'm having trouble for some reason. I used the example for multiple source files lazyfoo.net has and while it did help ease my confusion somewhat, I am still getting errors:

1>Pong.obj : error LNK2005: "struct SDL_Surface * sScreen" (?sScreen@@3PAUSDL_Surface@@A) already defined in Functions.obj
1>Pong.obj : error LNK2005: "int const SCREEN_WIDTH" (?SCREEN_WIDTH@@3HB) already defined in Functions.obj
1>Pong.obj : error LNK2005: "int const SCREEN_HEIGHT" (?SCREEN_HEIGHT@@3HB) already defined in Functions.obj
1>Pong.obj : error LNK2005: "int const SCREEN_BPP" (?SCREEN_BPP@@3HB) already defined in Functions.obj
1>Pong.obj : error LNK2005: "struct SDL_Surface * pongSprites" (?pongSprites@@3PAUSDL_Surface@@A) already defined in Functions.obj
1>C:\Users\Brandon\Documents\Visual Studio 2010\Projects\Pong\Release\Pong.exe : fatal error LNK1169: one or more multiply defined symbols found

Pong.cpp

#include "Functions.h"
#include "Globals.h"
#pragma region Main
int main(int argc, char* argv[])
{

#pragma region Setup
//Quit flag
    bool quit = false;
#pragma endregion Setup
#pragma region Game Logic
//While the user hasn't quit
    while( quit == false )
    {
  //While there's events to handle
	    while( SDL_PollEvent( &event ))
	    {
  
   //If the user has Xed out the window
		    if( event.type == SDL_QUIT )
		    {
			    //Quit the program
			    quit = true;
		    }
  }

#pragma endregion Game Logic
#pragma region Rendering
  SDL_FillRect(sScreen,NULL, 0x000000);
  //Update Screen
  SDL_Flip( sScreen );
#pragma endregion Rendering
}
return 0;
}
#pragma endregion Main

Globals.h

#ifndef GLOBALS_H
#define GLOBALS_H
#include "SDL.h"
#include "SDL_image.h"
extern SDL_Surface* sScreen = NULL;
extern const int SCREEN_HEIGHT = 700;
extern const int SCREEN_WIDTH = 600;
extern const int SCREEN_BPP = 32;
extern SDL_Event event;
extern SDL_Surface* pongSprites = NULL;
#endif

Functions.h

#ifndef FUNCTIONS_H
#define FUNCTIONS_H
#include "SDL.h"
#include "SDL_image.h"
#include <string>

bool init();
SDL_Surface *load_image( std::string filename );
void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* block );
bool load_files();

#endif

Functions.cpp

#include "Functions.h"
#include "SDL.h"
#include "SDL_image.h"
#include "Globals.h"
#include <string>

#pragma region Init

bool init()
{
//Initialize all SDL subsystems
    if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )
    {
	    return false;
    }
    //Set up the screen
    sScreen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );
//If there was an error in setting up the screen
    if( sScreen == NULL )
    {
	    return false;
    }
    //Set the window caption
    SDL_WM_SetCaption( "Pong", NULL );
    //If everything initialized fine
    return true;
}

#pragma endregion Init
#pragma region Load_image
//-------------------------------------------------
SDL_Surface *load_image( std::string filename )
{
    //The image that's loaded
    SDL_Surface* loadedImage = NULL;
    //The optimized surface that will be used
    SDL_Surface* optimizedImage = NULL;
    //Load the image
    loadedImage = IMG_Load( filename.c_str() );
    //If the image loaded
    if( loadedImage != NULL )
    {
	    //Create an optimized surface
	    optimizedImage = SDL_DisplayFormat( loadedImage );
	    //Free the old surface
	    SDL_FreeSurface( loadedImage );
	    //If the surface was optimized
	    if( optimizedImage != NULL )
	    {
		    //Color key surface
		    SDL_SetColorKey( optimizedImage, SDL_SRCCOLORKEY, SDL_MapRGB( optimizedImage->format, 0, 0xFF, 0xFF ) );
	    }
    }
    //Return the optimized surface
    return optimizedImage;
}
//-------------------------------------------------
#pragma endregion Load_image
#pragma region Load_Files
bool load_files()
{
  pongSprites = load_image("pong.png");
 
  if(pongSprites != NULL)
   return true;
  else
   return false;
}
#pragma endregion Load_Files
#pragma region Apply_Surface
void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* block )
{
  //Holds offsets
  SDL_Rect offset;
  //Get offsets
  offset.x = x;
  offset.y = y;
  //Blit
  SDL_BlitSurface( source, block, destination, &offset );
}
#pragma endregion Apply_Surface

Thank you for any help in getting over this next obstacle, I do appreciate it.

Sponsor:

#2 Brother Bob   Moderators   -  Reputation: 8196

Like
2Likes
Like

Posted 19 December 2012 - 04:55 AM

Don't do the assignment of the extern variables in the header file, that turns the extern declaration into a definition and your linker is complaining about multiple definitions. Only declare them with extern in the header, and define them without the extern in one source file.

header:
extern SDL_Surface* sScreen;
source:
SDL_Surface* sScreen = NULL;

You don't have to do the extern declaration for primitive const variables such as your integer, though. They have static linkage by default, so you can leave them in the header file but remove the extern from them.

#3 Álvaro   Crossbones+   -  Reputation: 13317

Like
2Likes
Like

Posted 19 December 2012 - 04:58 AM

extern SDL_Surface* sScreen = NULL;
extern const int SCREEN_HEIGHT = 700;
extern const int SCREEN_WIDTH = 600;
extern const int SCREEN_BPP = 32;
extern SDL_Event event;
extern SDL_Surface* pongSprites = NULL;


For sScreen and pngSprints (the non-const of the bunch), don't initialize them here. Instead, initialize them wherever you define them (a single .cpp file).

For SCREEN_HEIGHT, SCREEN_WIDTH and SCREEN_BPP (the const of the bunch), remove the `extern' and everything will work fine.

#4 sheep19   Members   -  Reputation: 392

Like
0Likes
Like

Posted 19 December 2012 - 11:17 AM

It would be even better to wrap your global variables in functions.

For example, for your SDL_Event event object, you could do something like:
SDL_Event& getGlobalEvent()
{
static SDL_Event event;
retrun event;
}
As it is static, it will be created only once (the first time it is called).

#5 Álvaro   Crossbones+   -  Reputation: 13317

Like
1Likes
Like

Posted 19 December 2012 - 12:27 PM

`event' should probably not be a global variable at all: It should be a local variable in `main', and it should be passed around only to functions that might need it.

#6 sheep19   Members   -  Reputation: 392

Like
0Likes
Like

Posted 19 December 2012 - 04:00 PM

Actually, none needs to be a global. You could pass event from main(), like alvaro suggested. You could do the same for pongSprites.
As for sScreen, you can remove it and use SDL_GetVideoSurface() when you need it.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS