使用标头编译时出错多个定义错误

时间:2016-07-31 05:25:37

标签: c++ makefile header g++ sdl

我的头文件和编译遇到了很多麻烦。我有一切与标题保护相关联,但由于某种原因,我仍然得到很多多重定义错误。我也在寻找更好的组织代码方法的帮助。无论如何帮助表示赞赏!

当我进行g ++调用时,这是我的控制台的输出输出:

g++ main.cpp close.cpp init.cpp load_media.cpp texture.cpp -w -lSDL2 -lSDL2_image -lSDL2_mixer -lSDL2_ttf -o run
/tmp/cc3oNgPs.o:(.bss+0x0): multiple definition of `g_font'
/tmp/ccg0hCKW.o:(.bss+0x0): first defined here
/tmp/cc3oNgPs.o:(.bss+0x8): multiple definition of `g_window'
/tmp/ccg0hCKW.o:(.bss+0x8): first defined here
/tmp/cc3oNgPs.o:(.bss+0x10): multiple definition of `g_renderer'
/tmp/ccg0hCKW.o:(.bss+0x10): first defined here
/tmp/cc3oNgPs.o:(.bss+0x20): multiple definition of `g_text_texture'
/tmp/ccg0hCKW.o:(.bss+0x20): first defined here
/tmp/ccIgzhbZ.o:(.bss+0x0): multiple definition of `g_font'
/tmp/ccg0hCKW.o:(.bss+0x0): first defined here
/tmp/ccIgzhbZ.o:(.bss+0x8): multiple definition of `g_window'
/tmp/ccg0hCKW.o:(.bss+0x8): first defined here
/tmp/ccIgzhbZ.o:(.bss+0x10): multiple definition of `g_renderer'
/tmp/ccg0hCKW.o:(.bss+0x10): first defined here
/tmp/ccIgzhbZ.o:(.bss+0x20): multiple definition of `g_text_texture'
/tmp/ccg0hCKW.o:(.bss+0x20): first defined here
/tmp/ccQs9gPv.o:(.bss+0x0): multiple definition of `g_font'
/tmp/ccg0hCKW.o:(.bss+0x0): first defined here
/tmp/ccQs9gPv.o:(.bss+0x8): multiple definition of `g_window'
/tmp/ccg0hCKW.o:(.bss+0x8): first defined here
/tmp/ccQs9gPv.o:(.bss+0x10): multiple definition of `g_renderer'
/tmp/ccg0hCKW.o:(.bss+0x10): first defined here
/tmp/ccQs9gPv.o:(.bss+0x20): multiple definition of `g_text_texture'
/tmp/ccg0hCKW.o:(.bss+0x20): first defined here
/tmp/ccxzUgM2.o:(.bss+0x0): multiple definition of `g_font'
/tmp/ccg0hCKW.o:(.bss+0x0): first defined here
/tmp/ccxzUgM2.o:(.bss+0x8): multiple definition of `g_window'
/tmp/ccg0hCKW.o:(.bss+0x8): first defined here
/tmp/ccxzUgM2.o:(.bss+0x10): multiple definition of `g_renderer'
/tmp/ccg0hCKW.o:(.bss+0x10): first defined here
/tmp/ccxzUgM2.o:(.bss+0x20): multiple definition of `g_text_texture'
/tmp/ccg0hCKW.o:(.bss+0x20): first defined here
collect2: error: ld returned 1 exit status

这是我的2个头文件:

isolation.h

//include //include guard
#ifndef ISOLATION_H
#define ISOLATION_H

//include dependencies
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_ttf.h>
#include <stdio.h>
#include <string>

//include headers
#include "texture.h"

//Screen dimension constants
const int SCREEN_WIDTH = 1280;
const int SCREEN_HEIGHT = 800;

//forward delcarlation
//class Texture;

//start up SDL create window
bool init();

//load all media
bool load_media();

//free all and shut down SDL
void close();

//load global front
TTF_Font* g_font = NULL;

//window
SDL_Window* g_window = NULL;

//renderer
SDL_Renderer* g_renderer = NULL;

//load jpeg + font
//Texture background_texture;

//rendered font texture
Texture g_text_texture;

#endif

texture.h

//include guard
#ifndef TEXTURE_H
#define TEXTURE_H

//include dependencies
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_ttf.h>
#include <stdio.h>
#include <string>

//include headers
//#include "isolation.h"

class Texture {
  public:
    //initializes variables
    Texture();

    //deallocates memory
    ~Texture();

    //load image from path
    bool load_from_file( std::string path );

    //create image from font string
    bool load_from_rendered_text( std::string textureText, SDL_Color text_color );

    //deallocates texture
    void free();

    //set color modulation
    void set_color( Uint8 red, Uint8 green, Uint8 blue );

    //set blend mode
    void set_blend_mode( SDL_BlendMode blending );

    //set alpha
    void set_alpha( Uint8 alpha );

    //render texture at point
    void render( int x, int y, SDL_Rect* clip = NULL, double angle = 0.0, SDL_Point* center = NULL, SDL_RendererFlip flip = SDL_FLIP_NONE ) const;

    //get image dimensions
    int get_width() const;
    int get_height() const;

  private:
    //texture pointer
    SDL_Texture* m_texture;

    //dimensions
    int m_width;
    int m_height;
};

#endif

init.cpp

#include "isolation.h"
//#include "texture.h"

bool init() {
  //initialization flag
  bool success = true;

  //initialize SDL
  if ( SDL_Init( SDL_INIT_VIDEO ) < 0 ) {
    printf( "SDL could not initialized. SDL Error: %s\n", SDL_GetError() );
    success = false;
  }
  else {
    //set texture filtering linear
    if ( !SDL_SetHint( SDL_HINT_RENDER_SCALE_QUALITY, "1" ) ) {
      printf( "Warning: Linear filtering not enabled\n" );
    }

    //create window
    g_window = SDL_CreateWindow( "Isolation", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN );
    if ( g_window == NULL ) {
      printf( "Window could not be created. SDL Error: %s\n", SDL_GetError() );
      success = false;
    }
    else {
      //create vsynced renderer
      g_renderer = SDL_CreateRenderer( g_window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC );
      if ( g_renderer == NULL ) {
        printf( "Renderer could not be created. SDL Error: %s\n", SDL_GetError() );
        success = false;
      }
      else {
        //initialize renderer color
        SDL_SetRenderDrawColor (g_renderer, 0xFF, 0xFF, 0xFF, 0xFF );

        //initialize JPEG loading
        int img_flags = IMG_INIT_JPG;
        if ( !( IMG_Init( img_flags ) & img_flags ) ) {
            printf( "SDL_image could not be initialize. SDL_image Error: %s\n", IMG_GetError() );
            success = false;
        }

        //initialize SDL_ttf
        if (TTF_Init() == -1 ) {
          printf( "SDL_ttf could not be initialize. SDL_ttf Error: %s\n", TTF_GetError() );
        }
      }
    }
  }

  return success;
}

load_media.cpp

#include "isolation.h"
//s#include "texture.h"

bool load_media() {
  bool success = true;

  //load background img
  //if( !background_texture.load_from_file( "img/vancouver.jpg" ) ) {
    //  printf( "Failed to load background texture!\n" );
    //  success = false;
    //}

  //open font
  g_font = TTF_OpenFont( "lazy.ttf", 28 );
  if ( g_font == NULL ) {
    printf( "Failed to load lazy font. SDL_ttf Error: %s\n", TTF_GetError() );
    success = false;
  }
  else {
    //render texture
    SDL_Color text_color = { 0, 0, 0 };
    if ( !g_text_texture.load_from_rendered_text( "hello from the other side ", text_color ) ) {
      printf( "Failed to render text texture\n" );
      success = false;
    }
  }

  return success;
}

close.cpp

#include "isolation.h"
//#include "texture.h"

void close() {
    //free loaded text
    g_text_texture.free();

    //free font
    TTF_CloseFont( g_font );
    g_font = NULL;

    //destroy window
    SDL_DestroyWindow( g_window );
    SDL_DestroyRenderer( g_renderer );
    g_window = NULL;
    g_renderer = NULL;

    //quit SDL subsystems
    TTF_Quit();
    IMG_Quit();
    SDL_Quit();
}

的main.cpp

#include "isolation.h"
//#include "texture.h"

int main( int argc, char* args[] ) {
  //start up SDL
  if ( !init() ) {
    printf( "Failed to initialize.\n" );
  }
  else {
    //load media
    if ( !load_media() ) {
      printf( "Failed to load media.\n" );
    }
    else{
      //main loop flag
      bool quit = false;

      //event handler
      SDL_Event e;

      //while running
      while ( !quit ) {
        //handle events on queue
        while ( SDL_PollEvent( &e ) != 0 ) {
          //user quit
          if ( e.type == SDL_QUIT ) {
            quit = true;
          }
        }

        //clear screen
        SDL_SetRenderDrawColor( g_renderer, 0xFF, 0xFF, 0xFF, 0xFF );
        SDL_RenderClear( g_renderer );

        //render frame
        g_text_texture.render( ( SCREEN_WIDTH - g_text_texture.get_width() ) / 2, ( SCREEN_HEIGHT - g_text_texture.get_height() ) / 2 );

        //update screen
        SDL_RenderPresent( g_renderer );
      }
    }
  }

  //free memory and close SDL
  close();

  return 0;
}

1 个答案:

答案 0 :(得分:1)

不要在.h文件中混合声明和定义/实例化。您正在g_font文件中实例化g_windowg_rendererisolation.h。正确的只是实例化一次,通常是在.cpp

要解决您的问题,请更改isolation.h以将这些变量声明为外部链接:

//load global front
extern TTF_Font* g_font;

//window
extern SDL_Window* g_window;

//renderer
extern SDL_Renderer* g_renderer;

并在应用的.cpp文件中仅对它们进行一次实例化,例如init.cpp