C-使用SDL的多个定义和未定义的引用

时间:2013-05-25 22:42:48

标签: c sdl

我已经搜索了我的错误解决方案,但它似乎永远无法解决我的问题。我不确定问题出在哪里,因为#includes似乎已经结束了。谢谢你的帮助。

错误:

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 $@ $(OBJECTS) $(LFLAGS)
$(OBJECTS) : $(SOURCES)
    gcc $< -c -o $@ $(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

2 个答案:

答案 0 :(得分:3)

前两行显示错误:

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

您正在编译test.c两次。

这是由Makefile中$<的错误使用引起的。它意味着在模式规则中使用,比如

.c.o:
        cc -c $< -o $@

或其中一个%.o%.c的更高级(不太便携)的GNU模式规则。

您的$(OBJECTS): $(SOURCES)不是模式规则。它只是一个常规规则,其中插入了一些预先计算的文件名列表。

答案 1 :(得分:0)

在我看来,你多次包括bool.h。如果你包含了包含bool.h的Button.h,那么就像在Button.c或test.c中一样,你不需要再次包含bool.h.这可能导致像这样的怪异行为。