【问题标题】:Error multiple definition when compiling using headers [closed]使用标头编译时出现多重定义错误[关闭]
【发布时间】:2016-12-05 11:34:41
【问题描述】:

我的头文件和编译遇到了很多麻烦。我将所有内容都与标头保护相关联,但由于某种原因,我仍然遇到很多多重定义错误。我也在寻找更好的组织代码方式的帮助。任何帮助表示赞赏!

这是我执行 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 个头文件:

隔离.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

纹理.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;
}

加载媒体.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;
}

关闭.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;
}

【问题讨论】:

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


    【解决方案1】:

    不要在 .h 文件中将声明与定义/实例化混为一谈。您正在 isolation.h 文件中实例化 g_fontg_windowg_renderer。正确的做法是只在 .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

    【讨论】:

    • 天哪,感谢它编译!谢谢我想知道编译器何时编译文件的顺序是否重要?例如,如果 init.cpp 中的 g_font 未编译,但其他源文件需要自己编译。
    • 通常,顺序很重要。但是,在这种情况下,如果 init.cpp 未编译,在链接阶段,您的链接器通常会回收未定义的内容,并中止生成可执行文件的过程
    猜你喜欢
    • 1970-01-01
    • 2022-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-23
    • 1970-01-01
    相关资源
    最近更新 更多