2017-04-26 4 views
1

방금 ​​C++과 SDL을 사용하기 시작했고, 기본 브레이크 아웃 클론을 작성하여 의미론을 둘러 보았습니다. 지금까지 모듈화를 위해 두 개의 헤더 파일 core.hpaddle.h을 만들었습니다.멀티 프로젝트 프로젝트에서 # SDL을 올바르게 포함합니다.

이러한 모듈에 SDL을 올바르게 포함시키는 데 어려움이 있습니다. 처음에 프로젝트는 제가 메인 파일 breakout.cpp, paddle.hpaddle.cpp 일 때 컴파일되었습니다. 이 단계에서 'Core'클래스는 breakout.cpp에 있으며, 파일을 자신의 파일로 마이그레이션하자마자 컴파일러가 화를 내기 시작했습니다. 나는 신인 감독을하고 있다고 생각하는 날 리드

breakout ---> core ---> paddle 

: 약자로

, 그것은 다음과 같이 설명 될 수있는 매우 간단한 설정이야. 또는 Makefile에서 파일을 잘못 연결하고 있습니다. 여기

코드이다

breakout.cpp

#include "SDL2/SDL.h" 
#include "SDL2/SDL_image.h" 
#include <stdio.h> 
#include <string> 
#include "core.h" 

int main(int argc, char* args[]) { 
    Core gCore; 
    gCore.runGame(); 

    return 0; 
} 

core.h

#pragma once 

#include "paddle.h" 

class Core { 
public: 
    Core(); 
    ~Core(); 
    void runGame(); 

private: 
    static const int SCREEN_WIDTH = 640, SCREEN_HEIGHT = 480; 

    SDL_Window* gWindow; 
    SDL_Renderer* gRenderer; 

    Paddle* p1; 

    void render(); 
}; 

paddle.h

#pragma once 

#include <string> 

class Paddle { 

    friend class Core; 

public: 
    Paddle(SDL_Renderer* gRenderer); 
    ~Paddle(); 

    void free(); 

private: 
    static const int VELOCITY = 5; 
    int xPos, yPos, pWidth, pHeight; 

    SDL_Texture* pSprite; 
    SDL_Rect* pRect; 

    bool loadFromFile(SDL_Renderer* gRenderer, std::string path); 

    int getXPos(); int getYPos(); 
    int getWidth(); int getHeight(); 
}; 

core.cpp

#include "SDL2/SDL.h" 
#include "SDL2/SDL_image.h" 
#include <stdio.h> 
#include "paddle.h" 
#include "core.h" 

Core::Core() { 

    // Set up SDL 
    if (SDL_Init(SDL_INIT_VIDEO) < 0) { 
     printf("SDL could not initialise! SDL Error: %s\n", SDL_GetError()); 
    } 
    else { 
     if (!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1")) { 
      printf("Warning: Linear texture filtering not enabled!"); 
     } 
     else { 
      gWindow = SDL_CreateWindow("SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, 
             SDL_WINDOW_SHOWN); 
      if (gWindow == NULL) { 
       printf("Could not create window. SDL Error: %s\n", SDL_GetError()); 
      } 
      else { 
       gRenderer = SDL_CreateRenderer(gWindow, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); 
       if (gRenderer == NULL) { 
        printf("Renderer could not be created! SDL Error: %s\n", SDL_GetError()); 
       } 
       else { 
        // Initialise renderer colour 
        SDL_SetRenderDrawColor(gRenderer, 0xFF, 0xFF, 0xFF, 0xFF); 

        // Initialise PNG loading 
        int imgFlags = IMG_INIT_PNG; 
        if (!(IMG_Init(imgFlags) & imgFlags)) { 
         printf("SDL_image could not be initialised! SDL_image Error: %s\n", IMG_GetError()); 
        } 
       } 
      } 
     } 
    } 
} 

Core::~Core() { 
    SDL_DestroyRenderer(gRenderer); gRenderer = NULL; 
    SDL_DestroyWindow(gWindow);  gWindow = NULL; 

    // Quit SDL subsystems 
    IMG_Quit(); 
    SDL_Quit(); 
} 

void Core::runGame() { 
    // Main loop flag 
    bool quit = false; 

    // Event handler 
    SDL_Event e; 

    // p1 = new Paddle(gRenderer); 

    while (!quit) { 
     while(SDL_PollEvent(&e) != 0) { 
      //User requests quit 
      if(e.type == SDL_QUIT) { 
       quit = true; 
      } 
     } 

     // Clear screen 
     SDL_SetRenderDrawColor(gRenderer, 0xFF, 0xFF, 0xFF, 0xFF); 
     SDL_RenderClear(gRenderer); 

     // Render game assets 
     render(); 

     // Update screen 
     SDL_RenderPresent(gRenderer); 
    } 
} 

void Core::render() { 
    // Set rendering space and render to screen 
    SDL_Rect pRenderQuad = { p1->xPos, p1->yPos, p1->pWidth, p1->pHeight }; 

    // Render to screen 
    SDL_RenderCopy(gRenderer, p1->pSprite, NULL, &pRenderQuad); 
} 

paddle.cpp

#include "SDL2/SDL.h" 
#include "SDL2/SDL_image.h" 
#include <stdio.h> 
#include <string> 
#include "paddle.h" 

Paddle::Paddle(SDL_Renderer* gRenderer) { 

    xPos = 300; yPos = 400; 
    pWidth = 0; pHeight = 0; 

    loadFromFile(gRenderer, "paddle.png"); 
} 

Paddle::~Paddle() { 
    free(); 
} 

bool Paddle::loadFromFile(SDL_Renderer* gRenderer, std::string path) { 
    // Get rid of preexisting texture 
    free(); 

    SDL_Texture* nTexture = NULL; 

    SDL_Surface* lSurface = IMG_Load(path.c_str()); 
    if (lSurface == NULL) { printf("Unable to load image %s! SDL_image Error: %s\n", path.c_str(), IMG_GetError()); } 
    else { 
     nTexture = SDL_CreateTextureFromSurface(gRenderer, lSurface); 
     if (nTexture == NULL) { printf("Unable to load texture from %s! SDL Error: %s\n", path.c_str(), SDL_GetError()); } 
     else { 
      pWidth = lSurface->w; 
      pHeight = lSurface->h; 
     } 

     SDL_FreeSurface(lSurface); // Surface no longer needed 
    } 

    pSprite = nTexture; 
    return pSprite != NULL; 
} 

void Paddle::free() { 
    if (pSprite != NULL) { 
     SDL_DestroyTexture(pSprite); 
     pWidth = 0; pHeight = 0; 
    } 
} 

// Getter methods 
int Paddle::getXPos() { return xPos; }  int Paddle::getYPos() { return yPos; } 
int Paddle::getWidth() { return pWidth; } int Paddle::getHeight() { return pHeight; } 

그리고 쉽게이 너무 문제가있을 수 있기 때문에 나는 또한, 메이크 파일을 포함했다.

메이크

OBJS = breakout.cpp 
DEPS = paddle.h core.h 

CC = g++ 

COMPILER_FLAGS = -w 

LINKER_FLAGS = -lSDL2 -lSDL2_image 

OBJ_NAME = breakout 

%.o: %.cpp $(DEPS) 
    $(CC) -c -o [email protected] $< $(COMPILER_FLAGS) 

all : $(OBJS) 
    $(CC) $(OBJS) $(COMPILER_FLAGS) $(LINKER_FLAGS) paddle.cpp core.cpp -o $(OBJ_NAME) 

오류 로그

g++ breakout.cpp -w -lSDL2 -lSDL2_image paddle.cpp core.cpp -o breakout 
/tmp/cc0H2fKM.o: In function `Paddle::loadFromFile(SDL_Renderer*, std::basic_string<char, std::char_traits<char>, std::allocator<char> >)': 
paddle.cpp:(.text+0x111): undefined reference to `IMG_Load' 
paddle.cpp:(.text+0x121): undefined reference to `SDL_GetError' 
paddle.cpp:(.text+0x15a): undefined reference to `SDL_CreateTextureFromSurface' 
paddle.cpp:(.text+0x16a): undefined reference to `SDL_GetError' 
paddle.cpp:(.text+0x1b8): undefined reference to `SDL_FreeSurface' 
/tmp/cc0H2fKM.o: In function `Paddle::free()': 
paddle.cpp:(.text+0x203): undefined reference to `SDL_DestroyTexture' 
/tmp/ccDHGaLY.o: In function `Core::Core()': 
core.cpp:(.text+0x12): undefined reference to `SDL_Init' 
core.cpp:(.text+0x1e): undefined reference to `SDL_GetError' 
core.cpp:(.text+0x44): undefined reference to `SDL_SetHint' 
core.cpp:(.text+0x86): undefined reference to `SDL_CreateWindow' 
core.cpp:(.text+0xa1): undefined reference to `SDL_GetError' 
core.cpp:(.text+0xd1): undefined reference to `SDL_CreateRenderer' 
core.cpp:(.text+0xee): undefined reference to `SDL_GetError' 
core.cpp:(.text+0x127): undefined reference to `SDL_SetRenderDrawColor' 
core.cpp:(.text+0x138): undefined reference to `IMG_Init' 
core.cpp:(.text+0x149): undefined reference to `SDL_GetError' 
/tmp/ccDHGaLY.o: In function `Core::~Core()': 
core.cpp:(.text+0x17a): undefined reference to `SDL_DestroyRenderer' 
core.cpp:(.text+0x195): undefined reference to `SDL_DestroyWindow' 
core.cpp:(.text+0x1a5): undefined reference to `IMG_Quit' 
core.cpp:(.text+0x1aa): undefined reference to `SDL_Quit' 
/tmp/ccDHGaLY.o: In function `Core::runGame()': 
core.cpp:(.text+0x1ea): undefined reference to `SDL_PollEvent' 
core.cpp:(.text+0x218): undefined reference to `SDL_SetRenderDrawColor' 
core.cpp:(.text+0x228): undefined reference to `SDL_RenderClear' 
core.cpp:(.text+0x244): undefined reference to `SDL_RenderPresent' 
/tmp/ccDHGaLY.o: In function `Core::render()': 
core.cpp:(.text+0x2d1): undefined reference to `SDL_RenderCopy' 
collect2: ld returned 1 exit status 
make: *** [all] Error 1 

는 정말 손이 아니라 문제에 대한 지원을 부탁드립니다 것입니다. 또한 내 코드에 대한 일반적인 제안이있을 수도 있습니다.

감사합니다.

+0

링커에서 SDL 라이브러리의 함수를 찾지 못합니다. 이것은 링커에 대한 인수의 순서로 인해 발생할 수 있습니다. Makefile에 .cpp 파일 다음에'LINKER_FLAGS'를 넣으십시오. –

+2

'-w'? * 왜? * - – Quentin

+0

Karsten Koop 제안에 감사드립니다. 즉시 문제가 해결되었습니다! 그리고 경고 제거 플래그를 사용하는 Quentin은 분명히 나쁜 생각입니다. 해당 플래그가 포함 된 것은 특정 SDL 자습서를 따름으로써 직접적인 결과였습니다. – manderc3

답변

3

컴파일러의 플래그 순서는 중요합니다.

링커에 전달할 라이브러리는 마지막에 있어야합니다.

그리고 그것은 -W 지침의 일종 다음 (자본), 보통의 같은 -w를 사용하는 것은 말이 안 등 -Werror -Wall 등

Suggesto : -w 플래그를 제거하고 -l 이동 끝으로 전환합니다.

+1

정확하지는 않습니다. 전혀 사용하지 않는 것보다 훨씬 나 빠릅니다 ('-w'는 gcc의 disable-all-warnings입니다). – keltar

관련 문제