1

In my file I can't figure out why I'm getting multiple definition errors. I'm getting them for an "SDL_Surface" called "screen".

screen is located within render.h. I've tried making it extern but it still throws an error. I've looked up quite a bit but I can't find a solution.

Here are the files in question:

main.cpp

//The headers
#include <iostream>
#include <string>
#include <vector>
#include "SDL/SDL.h"
#include "render.h"
#include "Entities.h"

//The surfaces that will be used
SDL_Surface *civilian = NULL;
SDL_Surface *background = NULL;

int main( int argc, char* args[])
{
    //initialize all of SDL systems
    INIT();

    //Load the images
    civilian = load_image("civilian.png");
    background = load_image("background.png");

    //Apply the background to the screen
    apply_surface(0,0, background, screen);

    //apply the civilian to the screen
    apply_surface(180, 140, civilian, screen);

    //update the screen
    if(SDL_Flip( screen ) == -1)
    {
        return 1;
    }

    //Wait 2 seconds
    SDL_Delay(2000);

    //free the surfaces
    SDL_FreeSurface(civilian);
    SDL_FreeSurface(background);

    //Quit SDL
    SHUTDOWN();

    return 0;
}

render.cpp

#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include <string>
#include "render.h"

bool INIT()
{
    //start SDL
    if (SDL_Init(SDL_INIT_EVERYTHING) == -1)
    {
        return false;
    };

    //Set up the screen
    screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE);

    //if there was an error setting up the screen
    if(screen == NULL)
    {
        return false;
    }

    //set the window caption
    SDL_WM_SetCaption("Zombie!", NULL);

    //if everything initialized fine
    return true;
}

void SHUTDOWN()
{
    //Free images eventually an if statement and array that stores all the images that need to be loaded
    // SDL_FreeSurface(image);

    //Quit SDL
    SDL_Quit();


}

//Optimized image loading function
SDL_Surface *load_image(std::string filename)
{
    //temporary storage for the image that's loaded
    SDL_Surface* loadedImage = NULL;
    //The optimized image that will be used
    SDL_Surface* optimizedImage = NULL;

    //Load the image
    loadedImage = IMG_Load(filename.c_str());

    //If nothing went wrong in loading the image
    if(loadedImage != NULL)
    {
        //Create an optimized image
        optimizedImage = SDL_DisplayFormat(loadedImage);

        //Free the old image
        SDL_FreeSurface(loadedImage);
    }
    return optimizedImage;
}


void apply_surface(int x, int y, SDL_Surface* source, SDL_Surface* destination)
{
    //Make a temporary rect to hold the offsets
    SDL_Rect offset;
    //Give the offsets to the rectangle
    offset.x = x;
    offset.y = y;

    //Blit the surface
    SDL_BlitSurface(source, NULL, destination, &offset);
}

/*bool load_files()
{
    //load the image
    image = load_image( "civilian.png");

    //If there was an error in loading the image
    if (image == NULL)
    {
        return false;
    }
    //if everything loaded fine
    return true;
}
*/

//Event handling
SDL_Event event;

render.h

#ifndef RENDER_H_INCLUDED
#define RENDER_H_INCLUDED

const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int SCREEN_BPP = 32;

SDL_Surface *screen = NULL;

struct Images
{
    std::string filename; //The name of the file to be loaded
    SDL_Surface* image; //set to null when created
    bool optimized; //set to false when created

};

extern Images ImageFiles[10];

//initialize all of SDL subsystems
bool INIT();

//quit SDL
void SHUTDOWN();

void apply_surface(int x, int y, SDL_Surface* source, SDL_Surface* destination);

//Optimized image loading function
SDL_Surface *load_image(std::string filename);

#endif // RENDER_H_INCLUDED

Here's the error:

obj\Debug\render.o||In function Z4INITv':| C:\Users\Joshua\Documents\CodeBlocks\Simulation\Zombie Survival\render.cpp|11|multiple definition ofscreen'| obj\Debug\main.o:C:\Users\Joshua\Documents\CodeBlocks\Simulation\Zombie Survival\main.cpp|20|first defined here| ||=== Build finished: 2 errors, 0 warnings (0 minutes, 1 seconds) ===|

4

2 回答 2

2

Remove SDL_Surface *screen = NULL; from render.h.
Declare SDL_Surface *screen = NULL; in render.cpp.
Declare extern SDL_Surface *screen; in main.cpp.

Since, a commentor asked for an explanation, I am explaining how C++ compiler behave.

C++ compiler compiles each source file (.cpp) as a single compilation unit. If SDL_Surface* screen = NULL; is declared in render.h, each compilation unit will have one copy of the global variable screen (see external linkage). Now, when the linker combines these compilation unit, it sees two copies of the same global variable name and errors out.

于 2013-10-19T00:24:31.643 回答
0

The simplest way to fix this problem is to open render.h and replace

SDL_Surface *screen = NULL;

with

SDL_Surface *screen;

Explanation:

Each time you include render.h from a different .cpp file, it will try to initialize the screen. This is a problem.

I've found that you can define screens multiple times, but you cannot initialize them multiple times.

于 2014-06-06T18:43:30.770 回答