Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Undefined reference problem z konsolidacją plików nagłówkowych

Ostatnio zmodyfikowano 2013-02-28 23:48
Autor Wiadomość
goovie
Temat założony przez niniejszego użytkownika
Undefined reference problem z konsolidacją plików nagłówkowych
» 2013-02-28 20:16:16
Oczywiscie spedzilem swoje kilka godzin z panem googlem i milionami innych forow programistycznych, gdzie inni mieli podobne problemy, niestety na zadnym z nich nie znalazlem odpowiedzi na moj problem. Przeczytalem takze kwadrylion tutoriali na necie, moja ksiazke z ktorej korzystam czasem podczas programowania, wyprobowalem kazdy pomysl jaki mi przychodzi do glowy, ale nie wiem gdzie jest blad (przebudowywanie, ponowne dodawanie plikow do projektu, dodawanie odpowiednich flag kompilatora w opcjach, wszystkie możliwe kombinacje dyrektyw include w roznych plikach, dodwanie extern przed definicjami funkcji i bog wie go co tam jeszcze - podczas 4h jakie spedzilem na rozwiazywnaiu tego problemu, rozwiazan bylo wiele).

Uzywam CodeBlocks 12.11 i kompilatora MinGW (g++).

Podczas pisania prostej gierki w allegro 4.2.2 moj kod zaczal sie troszke rozsrastac i postanowilem go elegancko sobie podzielic na rozne pliki. Oczywiscie stworzylem nowy projekt i dodalem odpowiednio "init.h" i "init.cpp" do projektu. Przeniosłem do "init.h" deklaracje funkcji i klas a do "init.cpp" ich definicje.


Niestety wywala mi błąd:
-------------- Build: Debug in CARS 2D (compiler: GNU GCC Compiler)---------------

mingw32-g++.exe -Wall    -ID:\DEVPAKS\include -IE:\Programy\CodeBlocks\MinGW\include  -c "C:\Documents and Settings\Przemek\Moje dokumenty\C++\ALLEGRO\CARS 2D\CARS 2D\main.cpp" -o obj\Debug\main.o
C:\Documents and Settings\Przemek\Moje dokumenty\C++\ALLEGRO\CARS 2D\CARS 2D\main.cpp: In function 'void samochodzik()':
C:\Documents and Settings\Przemek\Moje dokumenty\C++\ALLEGRO\CARS 2D\CARS 2D\main.cpp:5:17: error: 'car1' was not declared in this scope
C:\Documents and Settings\Przemek\Moje dokumenty\C++\ALLEGRO\CARS 2D\CARS 2D\main.cpp:8:14: error: 'track' was not declared in this scope
C:\Documents and Settings\Przemek\Moje dokumenty\C++\ALLEGRO\CARS 2D\CARS 2D\main.cpp:8:21: error: 'buffer' was not declared in this scope
In file included from C:\Documents and Settings\Przemek\Moje dokumenty\C++\ALLEGRO\CARS 2D\CARS 2D\main.cpp:1:0:
C:\Documents and Settings\Przemek\Moje dokumenty\C++\ALLEGRO\CARS 2D\CARS 2D\init.h: At global scope:
C:\Documents and Settings\Przemek\Moje dokumenty\C++\ALLEGRO\CARS 2D\CARS 2D\init.h:12:13: warning: inline function 'void init()' used but never defined [enabled by default]
C:\Documents and Settings\Przemek\Moje dokumenty\C++\ALLEGRO\CARS 2D\CARS 2D\init.h:13:13: warning: inline function 'void deinit()' used but never defined [enabled by default]
Process terminated with status 1 (0 minutes, 0 seconds)
3 errors, 2 warnings (0 minutes, 0 seconds)

Wnioskuje ze kompilator po prostu nie widzi definicji funkcji zawartych w pliku "init.cpp".

Zawartosci plikow:

main.cpp:
C/C++
#include "init.h"

void samochodzik()
{
    Car player1( car1, 0.5, 120, 370, ARROWS );
    while( true )
    {
        blit( track, buffer, 0, 0, 0, 0, track->w, track->h );
        player1.player_move();
        player1.move();
        player1.draw_on_buffer();
        blit( buffer, screen, 0, 0, 0, 0, buffer->w, buffer->h );
        clear_to_color( buffer, makecol( 255, 255, 255 ) );
        rest( 30 );
    }
}
int main()
{
    init();
   
    deinit();
    return 0;
}
END_OF_MAIN()

"init.h"

#ifndef init_h
#define init_h

#include <allegro.h>
#include <cmath>
#define grass_color 1024
#define road_color 50712
#define black_color 0
///deklaracje funkcji i klas:
enum control { WSAD, ARROWS };

inline void init();
inline void deinit();

class Car
{
private:
    double tab_sin[ 72 ];
    double tab_cos[ 72 ];
   
    const static int max_speed = 30; //maksymalna predkosc
    const static int min_speed = - 5; //minimalna predkosc (predkosc cofania)
    control keys;
    int x, y; //pozycja samochodu na ekranie
    int dx, dy; //przesuniecie samochodu wzgledem osi OX i OY
    int angle; //kat pod jakim jest samochod
    double speed; //obecna predkosc samochodu
    double acc; //przyspieszenie samochodu
    double friction; //tarcie powierzchni na jakiej znajduje sie auto
    BITMAP * sprite; // sprite z jakiego jest pobierany wyglad samochodu
   
    void fill_sin_cos();
    void increase_speed();
    void decrease_speed();
    void turn_right();
    void turn_left();
    void change_friction();
public:
    Car( BITMAP * _sprite, double _acc, int _x, int _y, control _keys ); //sprajt auta, przyspieszenie auta, wspolrzedne startowe, sposob sterowania (strzalki/wsad)
    void move(); //odpowiada za ruch autka na planszy
    void player_move();
    void draw_on_buffer(); //rysuje auto na buforze
   
};

#endif /* init_h */

"init.cpp":
C/C++
#include "init.h"
//deklaracje zmiennych globalnych:

BITMAP * car1 = NULL;
BITMAP * car2 = NULL;
BITMAP * track = NULL;
BITMAP * buffer = NULL;

const int Y_SIZE = 768;
const int X_SIZE = 1024;
//----------------------------------
inline void init()
{
    allegro_init();
    set_color_depth( 16 );
    set_gfx_mode( GFX_AUTODETECT_WINDOWED, X_SIZE, Y_SIZE, 0, 0 );
    car1 = load_bmp( "auto1.bmp", default_palette );
    car2 = load_bmp( "auto2.bmp", default_palette );
    track = load_bmp( "trasa.bmp", default_palette );
    buffer = create_bitmap( X_SIZE, Y_SIZE );
    install_timer();
    install_keyboard();
    install_mouse();
}
//----------------------------------------
inline void deinit()
{
    clear_keybuf();
    allegro_exit();
}
//----------------------------------------


//definicja klasy Car
Car::Car( BITMAP * _sprite, double _acc, int _x, int _y, control _keys )
{
    sprite = _sprite;
    acc = _acc;
    x = _x;
    y = _y;
    dx = dy = speed = angle = friction = 0;
    keys = _keys;
    fill_sin_cos();
   
}
//----------------------------------------
void Car::fill_sin_cos()
{
    for( int i = 0; i < 72; i++ )
    {
        tab_sin[ i ] = sin(( M_PI *( i * 5 ) ) / 180 );
        tab_cos[ i ] = cos(( M_PI *( i * 5 ) ) / 180 );
    }
}
//----------------------------------------
void Car::increase_speed()
{
    if( speed < max_speed ) speed += acc;
   
}
//----------------------------------------
void Car::decrease_speed()
{
    if( speed > min_speed ) speed -= acc;
   
}
//----------------------------------------
void Car::turn_right()
{
    if( angle < 71 )
         angle++;
    else
         angle = 0;
   
}
//----------------------------------------
void Car::turn_left()
{
    if( angle > 0 )
         angle--;
    else
         angle = 71;
   
}
//----------------------------------------
void Car::change_friction()
{
   
    int ground = getpixel( track, x + 30, y + 30 ); //wspolrzedne +30 poniewaz odczytujemy 'ze srodka' autka
    switch( ground )
    {
    case black_color:
    case road_color:
        friction = 0.2;
        break;
    case grass_color:
        friction = 0.45;
        break;
    default:
        friction = 0.2;
    }
}
//----------------------------------------
void Car::player_move()
{
    if( keypressed() )
    {
        switch( keys )
        {
        case ARROWS:
            if( key[ KEY_UP ] ) increase_speed();
           
            if( key[ KEY_DOWN ] ) decrease_speed();
           
            if( key[ KEY_RIGHT ] ) turn_right();
           
            if( key[ KEY_LEFT ] ) turn_left();
           
        case WSAD:
            if( key[ KEY_W ] ) increase_speed();
           
            if( key[ KEY_S ] ) decrease_speed();
           
            if( key[ KEY_D ] ) turn_right();
           
            if( key[ KEY_A ] ) turn_left();
           
        }
    }
}
//----------------------------------------
void Car::move()
{
    dx += speed * tab_cos[ angle ];
    dy += speed * tab_sin[ angle ];
    if( dx >= 1 || dx <= - 1 )
    {
        x += int( dx );
        dx = dx - int( dx );
    }
    if( dy >= 1 || dy <= - 1 )
    {
        y += int( dy );
        dy = dy - int( dy );
    }
   
    //obsluguje tarcie:
    if( speed < friction && speed > 0 ) speed = 0;
   
    if( speed > friction && speed < 0 ) speed = 0;
   
    if( speed > 0 ) speed -= friction;
   
    if( speed < 0 ) speed += friction;
   
    //powoduje zderzenia z brzegami planszy
    if( x <= 0 )
    {
        speed = 0;
        x = 1;
    }
    if( y <= 0 )
    {
        speed = 0;
        y = 1;
    }
    if( x >= X_SIZE - 60 )
    {
        speed = 0;
        x = X_SIZE - 61;
    }
    if( y >= Y_SIZE - 60 )
    {
        speed = 0;
        y = Y_SIZE - 61;
    }
}
//----------------------------------------
void Car::draw_on_buffer()
{
    masked_blit( sprite, buffer, 60 *( angle % 18 ), 60 *(( angle ) / 18 ), x, y, 60, 60 );
    textprintf_ex( buffer, font, X_SIZE - 130, Y_SIZE - 50, makecol( 0, 0, 0 ), - 1, "Predkosc: %.2f km/h", speed ); //wyswietla predkosc
    textprintf_ex( buffer, font, X_SIZE - 130, Y_SIZE - 60, makecol( 0, 0, 0 ), - 1, "Kierunek: %d", angle );
    textprintf_ex( buffer, font, X_SIZE - 130, Y_SIZE - 70, makecol( 0, 0, 0 ), - 1, "(x,y): %d %d", x, y );
    textprintf_ex( buffer, font, X_SIZE - 130, Y_SIZE - 80, makecol( 0, 0, 0 ), - 1, "Tarcie %.2f", friction );
}

"init.h"

C/C++
#ifndef init_h
#define init_h

#include <allegro.h>
#include <cmath>
#define grass_color 1024
#define road_color 50712
#define black_color 0
///deklaracje funkcji i klas:
enum control { WSAD, ARROWS };

inline void init();
inline void deinit();

class Car
{
private:
    double tab_sin[ 72 ];
    double tab_cos[ 72 ];
   
    const static int max_speed = 30; //maksymalna predkosc
    const static int min_speed = - 5; //minimalna predkosc (predkosc cofania)
    control keys;
    int x, y; //pozycja samochodu na ekranie
    int dx, dy; //przesuniecie samochodu wzgledem osi OX i OY
    int angle; //kat pod jakim jest samochod
    double speed; //obecna predkosc samochodu
    double acc; //przyspieszenie samochodu
    double friction; //tarcie powierzchni na jakiej znajduje sie auto
    BITMAP * sprite; // sprite z jakiego jest pobierany wyglad samochodu
   
    void fill_sin_cos();
    void increase_speed();
    void decrease_speed();
    void turn_right();
    void turn_left();
    void change_friction();
public:
    Car( BITMAP * _sprite, double _acc, int _x, int _y, control _keys ); //sprajt auta, przyspieszenie auta, wspolrzedne startowe, sposob sterowania (strzalki/wsad)
    void move(); //odpowiada za ruch autka na planszy
    void player_move();
    void draw_on_buffer(); //rysuje auto na buforze
   
};

#endif /* init_h */
P-77335
Monika90
» 2013-02-28 23:48:20
zmienne globalne muszą być zadeklarowane w init.h
C/C++
extern BITMAP * car1;
extern BITMAP * car2;
extern BITMAP * track;
extern BITMAP * buffer;
a zdefiniowane w init.cpp, tak jak są teraz:
C/C++
BITMAP * car1 = NULL;
BITMAP * car2 = NULL;
BITMAP * track = NULL;
BITMAP * buffer = NULL;

funkcje
inline
 za to muszą być zdefiniowane w nagłówku.
W twoim przypadku, najlepiej po prostu usunąć słowo
inline
.
P-77350
« 1 »
  Strona 1 z 1