PDA

Prikaži potpunu verziju : Problem, game engine u SDL-u


boshkodj
8.7.2009, 0:15
Poceo sam da pravim engine u SDL-u i naisao sam na jedan veoma cudan problem. Imam jedan game.h fajl u kome se nalazi klasa ,i game.cpp u kome sam "deklarisao" tu klasu. I onda mi se pojave dosta cudne greske :

main.obj : error LNK2005: "class Sprite pozadina" (?pozadina@@3VSprite@@A) already defined in Game.obj
main.obj : error LNK2005: "public: void __thiscall Sprite::Render(int,int,struct SDL_Surface *)" (?Render@Sprite@@QAEXHHPAUSDL_Surface@@@Z) already defined in Game.obj
main.obj : error LNK2005: "public: void __thiscall Sprite::Get_Picture(char const *)" (?Get_Picture@Sprite@@QAEXPBD@Z) already defined in Game.obj
main.obj : error LNK2005: "void __cdecl apply_surface(int,int,struct SDL_Surface *,struct SDL_Surface *,struct SDL_Rect *)" (?apply_surface@@YAXHHPAUSDL_Surface@@0PAUSDL_Rect @@@Z) already defined in Game.obj
main.obj : error LNK2005: "struct SDL_Surface * __cdecl load_image(char const *)" (?load_image@@YAPAUSDL_Surface@@PBD@Z) already defined in Game.obj
C:\Documents and Settings\korisnik\My Documents\Visual Studio 2008\Projects\SDL - vezbe\Release\SDL - vezbe.exe : fatal error LNK1169: one or more multiply defined symbols found
Build log was saved at "file://c:\Documents and Settings\korisnik\My Documents\Visual Studio 2008\Projects\SDL - vezbe\SDL - vezbe\Release\BuildLog.htm"

Ove greske mi se pojave kad imam game.cpp i game.h ,ali mi se ne pojave kad je klasa deklarisana u game.h
Evo vec sav kod tog engine - a:

Event.h:

#ifndef _EVENT_H
#define _EVENT_H

#include "SDL.h"

SDL_Event event;

#endif


Image.h:

#ifndef _IMAGE_H
#define _IMAGE_H

#include "SDL.h"
#include "SDL_image.h"


SDL_Surface *load_image( const char *name )
{

SDL_Surface* loadedImage = NULL;

SDL_Surface* optimizedImage = NULL;


loadedImage = IMG_Load( name );


if( loadedImage != NULL )
{

optimizedImage = SDL_DisplayFormat( loadedImage );


SDL_FreeSurface( loadedImage );

if( optimizedImage != NULL )
{

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* destination , SDL_Rect *clip = NULL )
{

SDL_Rect offset;


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


SDL_BlitSurface( source,clip , destination, &offset );
}

#endif


Sprite.h:

#ifndef _SPRITE_H
#define _SPRITE_H

#include "Image.h"

class Sprite
{
private:

SDL_Surface *picture ;

public:

void Get_Picture(const char *path);
void Render(int X_pos,int Y_pos,SDL_Surface *render_screen);
};
void Sprite::Get_Picture(const char *path)
{
picture = load_image(path);
}
void Sprite::Render(int X_pos, int Y_pos, SDL_Surface *render_screen)
{
apply_surface(X_pos,Y_pos,picture,render_screen);
}
#endif


game.h

#ifndef _GAME_H
#define _GAME_H

#include "Image.h"
#include "Sprite.h"

Sprite pozadina ;

class Game
{
private:

SDL_Surface *screen ;
int x ;
int y ;

public:

void GameStart(int X,int Y) ;
void GameLoop();
void GameEnd();
};

#endif


game.cpp

#include "Game.h"
#include "Sprite.h"

void Game::GameStart(int X,int Y)
{
x = X;
y = Y;

SDL_Init(SDL_INIT_EVERYTHING);
screen = SDL_SetVideoMode(x,y,32,SDL_SWSURFACE);

pozadina.Get_Picture("pozadina.bmp");
}
void Game::GameLoop()
{
pozadina.Render(0,0,screen);
SDL_Flip(screen);
}
void Game::GameEnd()
{
SDL_Quit();
}


main.cpp

#include "Event.h"
#include "Image.h"
#include "Sprite.h"
#include "Game.h"

bool quit = false ;

Game game;

int main(int argc,char **argv)
{
game.GameStart(640,480);

while( quit == false )
{
while( SDL_PollEvent(&event) )
{
if(event.type == SDL_QUIT)
{
quit = true;
}
}

game.GameLoop();

}

game.GameEnd();

return 0;

}


E kad ovaj kod kompajliram pojave mi se greske koje sam naveo gore,a kada je kod ovakav:

game.h:

#ifndef _GAME_H
#define _GAME_H

#include "Image.h"
#include "Sprite.h"

Sprite pozadina ;

class Game
{
private:

SDL_Surface *screen ;
int x ;
int y ;

public:

void GameStart(int X,int Y) ;
void GameLoop();
void GameEnd();
};
void Game::GameStart(int X,int Y)
{
x = X;
y = Y;

SDL_Init(SDL_INIT_EVERYTHING);
screen = SDL_SetVideoMode(x,y,32,SDL_SWSURFACE);

pozadina.Get_Picture("pozadina.bmp");
}
void Game::GameLoop()
{
pozadina.Render(0,0,screen);
SDL_Flip(screen);
}
void Game::GameEnd()
{
SDL_Quit();
}
#endif

,tada se ne pojavi ni jedna greska.

Molim vas pomozite! :(

rile
8.7.2009, 4:00
problem je u "image.h"

Da bi popravio na brzinu, dodaj "static" ispred definicija funkcija:

static SDL_Surface *load_image( const char *name )
{
...



static void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination , SDL_Rect *clip = NULL )
{
...



da bi popravio kako valja, ostavi deklaracije funkcija u image.h, dodaj image.cpp i u tom fajlu daj definicije (ali BEZ static).

boshkodj
8.7.2009, 10:54
:n-cc2: Sad se pojavljuju jos cudnije greske,prepravio sam kako si rekao i
Image.h je ovakav:

#ifndef _IMAGE_H
#define _IMAGE_H

#include "SDL.h"
#include "SDL_image.h"

static SDL_Surface *load_image( const char *name );
static void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination , SDL_Rect *clip = NULL );

#endif
i dodao sam image.cpp :

#include "Image.h"

SDL_Surface *load_image( const char *name )
{

SDL_Surface* loadedImage = NULL;

SDL_Surface* optimizedImage = NULL;


loadedImage = IMG_Load( name );


if( loadedImage != NULL )
{

optimizedImage = SDL_DisplayFormat( loadedImage );


SDL_FreeSurface( loadedImage );

if( optimizedImage != NULL )
{

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* destination , SDL_Rect *clip = NULL )
{

SDL_Rect offset;


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


SDL_BlitSurface( source,clip , destination, &offset );
}
i onda mi se pojava nerazumljive greske:

.\Image.cpp(37) : error C2572: 'apply_surface' : redefinition of default parameter : parameter 5
c:\documents and settings\korisnik\my documents\visual studio 2008\projects\sdl - vezbe\sdl - vezbe\Image.h(8) : see declaration of 'apply_surface'
main.cpp
.\main.cpp(33) : error C2129: static function 'void apply_surface(int,int,SDL_Surface *,SDL_Surface *,SDL_Rect *)' declared but not defined
c:\documents and settings\korisnik\my documents\visual studio 2008\projects\sdl - vezbe\sdl - vezbe\Image.h(8) : see declaration of 'apply_surface'
Game.cpp
.\Game.cpp(27) : error C2129: static function 'void apply_surface(int,int,SDL_Surface *,SDL_Surface *,SDL_Rect *)' declared but not defined
c:\documents and settings\korisnik\my documents\visual studio 2008\projects\sdl - vezbe\sdl - vezbe\Image.h(8) : see declaration of 'apply_surface'
Build log was saved at "file://c:\Documents and Settings\korisnik\My Documents\Visual Studio 2008\Projects\SDL - vezbe\SDL - vezbe\Release\BuildLog.htm"
SDL - vezbe - 3 error(s), 0 warning(s)

Andross
8.7.2009, 11:10
U cpp-u ti ne treba onaj = NULL za 5 argument za apply_surface. Citaj te greske malo :D

boshkodj
8.7.2009, 12:44
Ma na to nisam ni obracao paznju , evo sad sam obrisao null i poljavljuju mi se ove greske,koje nemaju veze s' vezom :

.\main.cpp(33) : error C2129: static function 'void apply_surface(int,int,SDL_Surface *,SDL_Surface *,SDL_Rect *)' declared but not defined
c:\documents and settings\korisnik\my documents\visual studio 2008\projects\sdl - vezbe\sdl - vezbe\Image.h(8) : see declaration of 'apply_surface'
Image.cpp
Game.cpp
.\Game.cpp(27) : error C2129: static function 'void apply_surface(int,int,SDL_Surface *,SDL_Surface *,SDL_Rect *)' declared but not defined
c:\documents and settings\korisnik\my documents\visual studio 2008\projects\sdl - vezbe\sdl - vezbe\Image.h(8) : see declaration of 'apply_surface'
Build log was saved at "file://c:\Documents and Settings\korisnik\My Documents\Visual Studio 2008\Projects\SDL - vezbe\SDL - vezbe\Release\BuildLog.htm"
SDL - vezbe - 2 error(s), 0 warning(s)

Zna neko u cemu je problem?

EclipsE
8.7.2009, 13:08
Nisi uopshte razumeo shta ti je rile napisao... Prochitaj post opet, nadam se da cesh shvatiti.

boshkodj
8.7.2009, 13:16
Nisi uopshte razumeo shta ti je rile napisao... Prochitaj post opet, nadam se da cesh shvatiti.
Mozes molim te da mi kazes sta je hteo da mi kaze posto ja nisam ociglendo lepo shvatio :( ??

rile
8.7.2009, 15:29
Rekao sam:

resenje 1:
stavi "static" ispred definicija funkcija, i sve ostalo ostavi kako si uradio pre. Pogledaj moj odgovor za primer kako treba da izgleda. U ovoj varijanti nemas image.cpp

resenje 2:
ostavi deklaracije kakve su ti u tvom originalnom primeru (bez static) pa stavi definicije (opet bez static, nego samo iskopriaj ono sto imas originalno u tvom image.h) u image.cpp. Znaci, u image.h ti ostaju DEKLARACIJE, u image.cpp definicije, i jedno i drugo bez "static".

Otprilike ovako:

image.h:

#ifndef _IMAGE_H
#define _IMAGE_H

#include "SDL.h"
#include "SDL_image.h"


SDL_Surface *load_image( const char *name );

void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination , SDL_Rect *clip = NULL );
#endif


Image.cpp:

#include "SDL.h"
#include "SDL_image.h"
#include "Image.h"

SDL_Surface *load_image( const char *name )
{

SDL_Surface* loadedImage = NULL;

SDL_Surface* optimizedImage = NULL;


loadedImage = IMG_Load( name );


if( loadedImage != NULL )
{

optimizedImage = SDL_DisplayFormat( loadedImage );


SDL_FreeSurface( loadedImage );

if( optimizedImage != NULL )
{

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* destination , SDL_Rect *clip /*= NULL*/ )
{

SDL_Rect offset;


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


SDL_BlitSurface( source,clip , destination, &offset );
}

boshkodj
8.7.2009, 17:11
Lepo sam shvatio,ovo prvo resenje ne pomaze :(
A za drugo resenje izbaci ove greske:

main.obj : error LNK2005: "public: void __thiscall Sprite::Render(int,int,struct SDL_Surface *)" (?Render@Sprite@@QAEXHHPAUSDL_Surface@@@Z) already defined in Game.obj
main.obj : error LNK2005: "public: void __thiscall Sprite::Get_Picture(char const *)" (?Get_Picture@Sprite@@QAEXPBD@Z) already defined in Game.obj
C:\Documents and Settings\korisnik\My Documents\Visual Studio 2008\Projects\SDL - vezbe\Release\SDL - vezbe.exe : fatal error LNK1169: one or more multiply defined symbols found
Build log was saved at "file://c:\Documents and Settings\korisnik\My Documents\Visual Studio 2008\Projects\SDL - vezbe\SDL - vezbe\Release\BuildLog.htm"
SDL - vezbe - 3 error(s), 0 warning(s)

Zna neko? :paranoia:

Patton
8.7.2009, 17:15
Probaj da uradis Clean Solution ili kako se vec to zove pa Rebuild.

boshkodj
8.7.2009, 17:58
Probaj da uradis Clean Solution ili kako se vec to zove pa Rebuild.
Isto :n-cc2:

rile
8.7.2009, 23:34
nije moguce da je isto, daj kakve greske dobijas. Iz tvoje prve poruke:
main.obj : error LNK2005: "void __cdecl apply_surface(int,int,struct SDL_Surface *,struct SDL_Surface *,struct SDL_Rect *)" (?apply_surface@@YAXHHPAUSDL_Surface@@0PAUSDL_Rect @@@Z) already defined in Game.obj
main.obj : error LNK2005: "struct SDL_Surface * __cdecl load_image(char const *)" (?load_image@@YAPAUSDL_Surface@@PBD@Z) already defined in Game.obj

prilicno sam siguran da ne dobijas ove dve greske ni u varijanti 1 ni u varijanti2.

Ostatak gresaka je sa sprite.h: napravi sprite.cpp i prebaci definicije metoda tamo (Sprite::Get_Picture i Sprite::Render).

boshkodj
8.7.2009, 23:48
Za prvo resenje mi izadju greske koje sam napisao u postu 5 ,a za drugo resenje greske koje sam napisao u postu 9.

Hvala svima,problem je bio u tome sto definicije za Sprite klasu nisam stavio u poseban fajl(sprite.cpp)
Hvala opet svima posebno RILETU :)

rile
9.7.2009, 3:57
Bilo bi dobro da prodjemo jos jednom varijantu 1. Nesto si uradio drugacije od onoga sto sam ti rekao, jer da si uradio tacno kako sam rekao jednostavno ne bi mogao da ti da iste greske. Ponovio bi greske o Sprite metodama, ali za ove dve funkcije ne.

O cemu se radi: greske koje si dobio je prijavio linker. Kompajler je sve iskompajlirao dobro, ali se linker pobunio kada je razresavao simbole funkcija: nije mogao da odredi koju treba da uzme.

Odakle visestruke definicije?

Svaki od .cpp fajlova je jedna "kompilaciona jedinica". Svaka kompilaciona jedinica daje jedan ".o" ili ".obj" objektni fajl. Taj fajl sadrzi masinski kod (vec preveden) i tabelu simbola, jer u trenutku kompajliranja ne moze da se zna gde je adresa funkcije koja se poziva.

Kako si definicije datih funkcija (i metoda) dao u .h fajlu, za svaku kompilacionu jedinicu si dobio po jednu kopiju masinskog koda; u trenutku linkovanja, linker na mestu poziva tih funkcija pokusava da razresi simbol i nadje njegovu adresu, ali nalazi vise od jedne i buni se.

Dodvanjem "static" govoris da data funkcija ne moze biti pozivana van date kompilacione jedinice gde je definisana. Tako svaka kompilaciona jedinica poziva svoju definiciju.

Metode ne mozes tako "lako" da resis, jer static u slucaju metoda ima drugo znacenje.

boshkodj
9.7.2009, 11:07
Ali kada stavim static ispred ove dve funkcije izadje mi greska da je apply_surface deklarisan ali ne i definisan ,evo kako sam uradio:

image.h

#ifndef _IMAGE_H
#define _IMAGE_H

#include "SDL.h"
#include "SDL_image.h"

static SDL_Surface *load_image( const char *name );

static void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination , SDL_Rect *clip = NULL );


#endif


image.cpp

#include "Image.h"

SDL_Surface *load_image( const char *name )
{

SDL_Surface* loadedImage = NULL;

SDL_Surface* optimizedImage = NULL;


loadedImage = IMG_Load( name );


if( loadedImage != NULL )
{

optimizedImage = SDL_DisplayFormat( loadedImage );


SDL_FreeSurface( loadedImage );

if( optimizedImage != NULL )
{

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* destination , SDL_Rect *clip /*= NULL*/ )
{

SDL_Rect offset;


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


SDL_BlitSurface( source,clip , destination, &offset );
}


A izadje ova greska:

.\Sprite.cpp(12) : error C2129: static function 'void apply_surface(int,int,SDL_Surface *,SDL_Surface *,SDL_Rect *)' declared but not defined
c:\documents and settings\korisnik\my documents\visual studio 2008\projects\sdl - vezbe\sdl - vezbe\Image.h(9) : see declaration of 'apply_surface'

:eek: ??

Andross
9.7.2009, 13:59
Ama bre citas li ti sta ti se pise?
Static koristi ako hoces da ti definicija bude u .h fajlu u suprotnom ga ne koristis (sem ako nemas neku specijalnu namenu) :dedica:

boshkodj
9.7.2009, 14:48
Ama bre citas li ti sta ti se pise?
Static koristi ako hoces da ti definicija bude u .h fajlu u suprotnom ga ne koristis (sem ako nemas neku specijalnu namenu) :dedica:
aha :D