2013-05-25 65 views
0

我對我的錯誤使用了Google解決方案,但似乎從未解決我的問題。我不確定問題出在哪裏,因爲#includes似乎在檢查。感謝您的幫助。C-與SDL的多重定義和未定義參考

錯誤:

gcc test.c -c -o test.o 
gcc test.c -c -o Button.o 
gcc -o test test.o Button.o -lmingw32 -lSDLmain -lSDL -lSDL_image -Wl,-subsystem 
,windows 
Button.o:test.c:(.text+0x0): multiple definition of `SDL_main' 
test.o:test.c:(.text+0x0): first defined here 
Button.o:test.c:(.text+0x152): multiple definition of `init' 
test.o:test.c:(.text+0x152): first defined here 
Button.o:test.c:(.text+0x1c3): multiple definition of `load_image' 
test.o:test.c:(.text+0x1c3): first defined here 
Button.o:test.c:(.text+0x252): multiple definition of `apply_surface' 
test.o:test.c:(.text+0x252): first defined here 
test.o:test.c:(.text+0x15): undefined reference to `Button_size' 
test.o:test.c:(.text+0x91): undefined reference to `Button_constr' 
test.o:test.c:(.text+0xb8): undefined reference to `Button_handleEvents' 
test.o:test.c:(.text+0x11b): undefined reference to `Button_show' 
Button.o:test.c:(.text+0x15): undefined reference to `Button_size' 
Button.o:test.c:(.text+0x91): undefined reference to `Button_constr' 
Button.o:test.c:(.text+0xb8): undefined reference to `Button_handleEvents' 
Button.o:test.c:(.text+0x11b): undefined reference to `Button_show' 
collect2: ld returned 1 exit status 
mingw32-make: *** [test] Error 1 

生成文件:

LFLAGS = -lmingw32 -lSDLmain -lSDL -lSDL_image -Wl,-subsystem,windows 
CFLAGS = 
SOURCES =test.c Button.c 
EXECUTABLE =test 

OBJECTS = $(SOURCES:.c=.o) 

all: $(EXECUTABLE) 
$(EXECUTABLE): $(OBJECTS) 
    gcc -o [email protected] $(OBJECTS) $(LFLAGS) 
$(OBJECTS) : $(SOURCES) 
    gcc $< -c -o [email protected] $(CFLAGS) 

.PHONY: clean 

clean: 
    del /Q *.o *.exe 

test.c的

#include "SDL/SDL.h" 
#include "SDL/SDL_image.h" 
#include "bool.h" 
#include "Button.h" 

#define TEST_SCREEN_WIDTH 640 
#define TEST_SCREEN_HEIGHT 480 
#define TEST_SCREEN_BPP 32 

SDL_Surface *load_image(char* filename); 
void apply_surface(int x, int y, SDL_Surface* source, SDL_Surface* dest, SDL_Rect* clip); 
bool init(SDL_Surface** screen); 
bool load_files(SDL_Surface** image); 
void clean_up(SDL_Surface* image); 

int main(int argc, char* args[]) 
{ 

    SDL_Surface* screen = NULL; 
    SDL_Surface* buttonSheet = NULL; 
    Button* myButton; 
    myButton = malloc(Button_size()); 
    SDL_Event event; 

    if(!init(&screen)) return 1; 
    bool quit = false; 

    if(! (buttonSheet = load_image("button.png"))) return 1; 

    if(!Button_constr(myButton, buttonSheet, 170,120,320,240)); 

    while(!quit) 
    { 

     while(SDL_PollEvent(&event)) 
     { 

      if(event.type == SDL_QUIT) quit = true; 
      else Button_handleEvents(myButton, &event); 

     } 

     SDL_FillRect(screen, &screen->clip_rect, SDL_MapRGB(screen->format, 0xFF, 0xFF, 0xFF)); 

     Button_show(myButton, screen); 

     if(SDL_Flip(screen)) return 1; 

    } 

    free(myButton); 
    SDL_Quit(); 
    return 0; 
} 



bool init(SDL_Surface** screen) 
{ 

    if(SDL_Init(SDL_INIT_EVERYTHING)) return false; 

    (*screen) = SDL_SetVideoMode(TEST_SCREEN_WIDTH,TEST_SCREEN_HEIGHT,TEST_SCREEN_BPP,SDL_SWSURFACE); 

    if(!(*screen)) return false; 

    SDL_WM_SetCaption("Event test", NULL); 
    return true; 

} 

SDL_Surface *load_image(char* filename) 
{ 

    SDL_Surface* loadedImage = NULL; 
    SDL_Surface* optimizedImage = NULL; 

    loadedImage = IMG_Load(filename); 

    if(loadedImage) 
    { 

     optimizedImage = SDL_DisplayFormat(loadedImage); 
     SDL_FreeSurface(loadedImage); 

     if(optimizedImage) 
     { 

      Uint32 colorkey = SDL_MapRGB(optimizedImage->format, 0, 0xFF, 0xFF); 
      SDL_SetColorKey(optimizedImage, SDL_SRCCOLORKEY, colorkey); 

     } 

    } 

    return optimizedImage; 


} 

void apply_surface(int x, int y, SDL_Surface* source, SDL_Surface* dest, SDL_Rect *clip) 
{ 

    SDL_Rect offset; 
    offset.x = x; 
    offset.y = y; 

    SDL_BlitSurface(source, clip, dest, &offset); 

} 

test.h:

#ifndef id250CBE4C_8C40_40EC_B4D7264D6B1E451C 
#define id250CBE4C_8C40_40EC_B4D7264D6B1E451C 

void apply_surface(int x, int y, SDL_Surface* source, SDL_Surface* dest, SDL_Rect* clip); 

#endif 

button.c的:

#include "SDL/SDL.h" 
#include "Button.h" 
#include "test.h" 
#include "bool.h" 

#define CLIP_MOUSEOVER 0 
#define CLIP_MOUSEOUT 1 
#define CLIP_MOUSEDOWN 2 
#define CLIP_MOUSEUP 3 

void Button_PRIVATE_setClips(Button* self); 

struct Button 
{ 

    SDL_Rect box; 
    SDL_Rect *clip; 
    SDL_Surface* image; 
    SDL_Rect clips[4]; 

}; 

int Button_size() 
{ 

    return sizeof(Button); 

} 

void Button_PRIVATE_setClips(Button* self) 
{ 

    self->clips[CLIP_MOUSEOVER].w = self->clips[CLIP_MOUSEOUT].w = self->clips[CLIP_MOUSEDOWN].w 
     = self->clips[CLIP_MOUSEUP].w = 320; 
    self->clips[CLIP_MOUSEOVER].h = self->clips[CLIP_MOUSEOUT].h = self->clips[CLIP_MOUSEDOWN].h 
     = self->clips[CLIP_MOUSEUP].h = 240; 

    self->clips[CLIP_MOUSEOVER].x = self->clips[CLIP_MOUSEOVER].y = 0; 
    self->clips[CLIP_MOUSEOUT].x = 320, self->clips[CLIP_MOUSEOUT].y = 0; 
    self->clips[CLIP_MOUSEDOWN].x = 0, self->clips[CLIP_MOUSEDOWN].y = 240; 
    self->clips[CLIP_MOUSEUP].x = 320, self->clips[CLIP_MOUSEUP].y = 240; 

} 

bool Button_constr(Button* self, SDL_Surface* image, int x, int y, int w, int h) 
{ 

    Button_PRIVATE_setClips(self); 

    self->box.x=x; 
    self->box.y=y; 
    self->box.w=w; 
    self->box.h=h; 

    self->clip = &self->clips[CLIP_MOUSEOUT]; 

} 

void Button_handleEvents(Button* self, SDL_Event* event) 
{ 

    int x=0, y=0; 
    SDL_GetMouseState(&x,&y); 
    self->clip = &self->clips[CLIP_MOUSEOUT]; 

    if((x> self->box.x) && (x< self->box.x+self->box.w) 
     && (y> self->box.y) && (y< self->box.y+self->box.h)) 
    { 

     if(event->type == SDL_MOUSEMOTION) self->clip = &self->clips[CLIP_MOUSEOVER]; 
     else if(event->type == SDL_MOUSEBUTTONDOWN && event->button.button == SDL_BUTTON_LEFT) 
      self->clip = &self->clips[CLIP_MOUSEDOWN]; 
     else if(event->type == SDL_MOUSEBUTTONUP && event->button.button == SDL_BUTTON_LEFT) 
      self->clip = &self->clips[CLIP_MOUSEUP]; 

    } 


} 

void Button_show(Button* self, SDL_Surface* screen) 
{ 

    apply_surface(self->box.x, self->box.y, self->image, screen, self->clip); 
} 

Button.h:

#ifndef id5CB3FF3A_7168_477D_AAFF0F481C46197C 
#define id5CB3FF3A_7168_477D_AAFF0F481C46197C 

#include "bool.h" 

typedef struct Button Button; 
//constructor 
bool Button_constr(Button* self, SDL_Surface* image, int x, int y, int w, int h); 
int Button_size(); 
void Button_handleEvents(Button* self, SDL_Event* event); 
void Button_show(Button* self, SDL_Surface* screen); 

#endif 

bool.h:

#ifndef idF3FFBDD5_86AB_4992_88037678AEADE02B 
#define idF3FFBDD5_86AB_4992_88037678AEADE02B 

typedef enum{false, true} bool; 

#endif 

回答

3

第2行清楚地顯示出錯誤:

gcc test.c -c -o test.o 
gcc test.c -c -o Button.o 

你正在編譯test.c兩次。

這是由於在Makefile中錯誤使用$<引起的。它意味着在圖案規則中使用,像

.c.o: 
     cc -c $< -o [email protected] 

或的發燒友(以下便攜式)GNU圖案%.o%.c規則之一。您的$(OBJECTS): $(SOURCES)不是模式規則。這只是一個常規規則,其中包含一些預先計算的文件名列表。

+0

非常感謝! – caps

0

在我看來,你包括bool.h多次。如果你包含了包含bool.h的Button.h,那麼你不需要像在Button.c或test.c中那樣再次包含bool.h。這可能會導致這樣的怪異行爲。