• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

SDL2 ld returned 1 exit status oraz first defined here

Object Storage Arubacloud
0 głosów
393 wizyt
pytanie zadane 25 lipca 2016 w C i C++ przez Bot Użytkownik (760 p.)

Postanowiłem napisać jakiś prosty kod w c++, cały czas robiłem kopie zapasowe, tak by łatwiej było mi znaleźć błędy. Utknąłem na banalnych błędach : "error: first defined here"(początek funkcji frame_1 w pliku "frame.cpp") oraz "ld returned 1 exit status"(wiem, że są to podstawowe błędy, ale po 6h szukania błędu-źle to o mnie świadczy, nadal nie znalazłem błędu, więc proszę o pomoc).

Biblioteki:

-SDL2

-SDL2 image

-SDL2 ttf

-SDL2 mixer //chociaż nie użyłem ani razu

Oto cały kod(proszę o niezwracanie uwagi na komentarze oraz na to, że skrypt jest niedopracowany-na tym momencie utknąłem):

main.cpp

#include <SDL2/SDL.h>//
#include <SDL2/SDL_image.h>//
#include <SDL2/SDL_mixer.h>// include wszystkiego
#include <SDL2/SDL_ttf.h>// co potrzebne
#include "framy.h"//
#include "licznik.h"
using namespace std;

SDL_Window * okno;
SDL_Surface * ekran;
int frame =0;
bool tryb_test(true);
int main(int argc, char*args[])
{
SDL_Init(SDL_INIT_EVERYTHING);
TTF_Init();
okno= SDL_CreateWindow(licznik(), SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED, 800,600,0);
ekran = SDL_GetWindowSurface(okno);
while(true)
{
    if(frame==0)//frame 0
    {// wszytsko co nalezy do frame 0
        frame_1(okno,ekran,frame,tryb_test);
    }

}
}

Wszystkie pliki nagłówkowe

obiekt.h

#ifndef OBIEKT_H
#define OBIEKT_H
#include <SDL2/SDL.h>
#include <string>
#include <SDL2/SDL_image.h>
using namespace std;
class obiekt
{
    string sciezka_obecna;
    public:
        int x,y,h,w;
        SDL_Surface * powierzchnia;

        ///konstruktory
        obiekt();
        obiekt(string sciezka,int x,int y, int h, int w);
        obiekt(const obiekt & wzor); //kopiujacy
        obiekt(int x,int y, int h, int w);
        obiekt(int x,int y);
        ///destruktor
        virtual ~obiekt();
        ///funkcje
        void blitSU(SDL_Surface * na_co);
        void zmien_obiekt(string sciezka,int x=0, int y=0, int h=0, int w=0);
        void zmien_rect(int x=0, int y=0, int h=0, int w=0);
        void Sfree() {SDL_FreeSurface(powierzchnia);}
        void zmien_koordynaty(int x, int y)
        {
            obiekt::x=x;
            obiekt::y=y;
        }
        void zmien_obraz(string sciezka);
        bool kolizja(obiekt);
        ///konwersje
        operator SDL_Surface *()
        {
            return powierzchnia;
        }
        operator SDL_Rect();
        ///przeciazenie operatorow
        obiekt& operator=(const obiekt & wzor);
};

#endif // OBIEKT_H

licznik.h


#ifndef LICZNIK_H_INCLUDED
#define LICZNIK_H_INCLUDED
#include<SDL2/SDL.h>
const char * licznik();
void sterowanie(SDL_Window * okno, SDL_Surface * ekran,int & posX, int & posY);
void error(SDL_Window * okno, SDL_Surface * ekran);

#endif // LICZNIK_H_INCLUDED

funkcje_sterowania.h


#ifndef FUNKCJE_STEROWANIA_H_INCLUDED
#define FUNKCJE_STEROWANIA_H_INCLUDED
#include<SDL2/SDL.h>
void wyjscie();

#endif // FUNKCJE_STEROWANIA_H_INCLUDED

framy.h


#ifndef FRAMY_H_INCLUDED
#define FRAMY_H_INCLUDED
#include <SDL2/SDL.h>
void frame_1(SDL_Window * okno, SDL_Surface * ekran, int & frame, bool tryb_test);


#endif // FRAMY_H_INCLUDED

wydarzenia.h

#ifndef WYDARZENIA_H_INCLUDED
#define WYDARZENIA_H_INCLUDED
#include<SDL2/SDL.h>
void wydarzenia();
void wyj_Quit(SDL_Event& z);

#endif // WYDARZENIA_H_INCLUDED

pliki *.cpp:

obiekt.cpp

#include "obiekt.h"
#include<SDL2/SDL.h>
#include<string>
#include<SDL2/SDL_image.h>
using namespace std;
obiekt::~obiekt()
{
    Sfree();
    //dtor
}
obiekt::obiekt()
{
    x=0;y=0;h=0;w=0;
    sciezka_obecna="";
    //ctor
}
obiekt::obiekt(string sciezka,int x,int y, int h, int w)
{
    sciezka_obecna=sciezka;
    obiekt::x=x;
    obiekt::y=y;
    obiekt::h=h;
    obiekt::w=w;
    powierzchnia=IMG_Load(sciezka.c_str());
}
obiekt::obiekt(const obiekt & wzor)
{
    x=wzor.x;
    y=wzor.y;
    h=wzor.h;
    w=wzor.w;
    sciezka_obecna=wzor.sciezka_obecna;
    powierzchnia=IMG_Load(sciezka_obecna.c_str());
}
obiekt::obiekt(int x, int y, int h, int w)
{
    obiekt::x=x;
    obiekt::y=y;
    obiekt::h=h;
    obiekt::w=w;
}
obiekt::obiekt(int x, int y)
{
    obiekt::x=x;
    obiekt::y=y;
}
///funkcje
void obiekt::zmien_obiekt(string sciezka,int x, int y, int h, int w)
{
    sciezka_obecna=sciezka;
    obiekt::x=x;
    obiekt::y=y;
    obiekt::h=h;
    obiekt::w=w;
    Sfree();
    powierzchnia=IMG_Load(sciezka.c_str());
}
void obiekt::zmien_rect(int x, int y, int h, int w)
{
    obiekt::x=x;
    obiekt::y=y;
    obiekt::h=h;
    obiekt::w=w;
}
void obiekt::zmien_obraz(string sciezka)
{
    sciezka_obecna=sciezka;
    Sfree();
    powierzchnia=IMG_Load(sciezka.c_str());
}
void obiekt::blitSU(SDL_Surface * na_co)
{
    SDL_Rect wysylane;
    wysylane.x=x;
    wysylane.y=y;
    wysylane.h=h;
    wysylane.w=w;
    SDL_BlitSurface(powierzchnia,NULL,na_co,&wysylane);
}
bool obiekt::kolizja(obiekt V)
{
    if(V.x<=x+w && V.x>x && V.y>=y && V.y<=(y+h)) return true;
    else if(V.x<=(x+w) && V.x>x && (V.y+V.h)>=y && (V.y+V.h)<=(y+h)) return true;
    else if ((V.x+V.w)<=(x+w) && (V.x+V.w)>x && V.y>=y && V.y <= y+h) return true;
    else if((V.x+V.w)<=(x+w) && (V.x+V.w)>x && (V.y+V.h)>=y && (V.y+V.h)<=(y+h)) return true;
    else return false;
}
///operatory
obiekt::operator SDL_Rect()
{
    SDL_Rect zwracane;
    zwracane.x=x;
    zwracane.y=y;
    zwracane.h=h;
    zwracane.w=w;
    return zwracane;
}
obiekt & obiekt::operator=(const obiekt & wzor)
{
    x=wzor.x;
    y=wzor.y;
    h=wzor.h;
    w=wzor.w;
    return *this;
}

error.cpp

#include"licznik.h"
#include<SDL2/SDL_ttf.h>
#include<SDL2/SDL.h>
#include<cstdlib>
void error(SDL_Window * okno, SDL_Surface * ekran)
{
    TTF_Font * arialek = TTF_OpenFont("trzcionki/arial.ttf",100); //TRZCIONKA
    SDL_Color kolorek={0,0,0};
    SDL_Rect pozycja_bledu;
    pozycja_bledu.x=0;
    pozycja_bledu.y=0;
    SDL_Surface * tekst_error = TTF_RenderText_Blended(arialek,"ERROR", kolorek);
    SDL_BlitSurface(tekst_error,NULL,ekran,&pozycja_bledu);
    SDL_UpdateWindowSurface(okno);
    SDL_Delay(1500);
    SDL_FreeSurface(tekst_error);
    exit(0);
}

fps.cpp

#include<time.h>
#include<SDL2/SDL.h>
class klasa_fps
{
    int koniec_f,poczatek_f,roznica;
   float delay;
   const static int fps=60;
    void kontynuacja()
    {
        roznica = koniec_f-poczatek_f;
           delay=(1000.0)/fps-roznica;
           if(delay>0)
           {
               SDL_Delay(delay);
           }
    }
    public:
       void start()
       {
           poczatek_f=clock();
       }
       void koniec()
       {
           koniec_f=clock();
           kontynuacja();
       }
};

frame_1.cpp

#include <SDL2/SDL.h>//
#include <SDL2/SDL_image.h>//
#include <SDL2/SDL_mixer.h>// include wszystkiego
#include <SDL2/SDL_ttf.h>// co potrzebne
#include <sstream>//
#include "fps.cpp"//
#include "licznik.h"//
#include "wydarzenia.h"//
#include "obiekt.h"//
#include "funkcje_sterowania.h"//
#include <windows.h>//
#include "parametry.cpp"//
#include <iostream>//
#include "framy.h"
using namespace std;

void frame_1(SDL_Window * okno, SDL_Surface * ekran, int & frame, bool tryb_test)
{ // tu wyskakuje błąd
    obiekt postac("Grafika/obiekt_animacja1.bmp",100,385,72,22);
    obiekt tlo("Grafika/tlo.bmp",0,0,600,800);
    obiekt tekst(0,0);
    obiekt pozycje(550,0);
    obiekt chmura1("Grafika/chmura.bmp",15,15,134,209);
    obiekt chmura2("Grafika/chmura.bmp",275,15,134,209);
    obiekt chmura3("Grafika/chmura.bmp",540,15,134,209);
    obiekt gorna_BAR("Grafika/pozioma_bariera.bmp",0,-10,10,800);
    obiekt dolna_BAR("Grafika/pozioma_bariera.bmp",0,595,10,800);
    klasa_fps fps;//kontrola fps

    TTF_Font * arial = TTF_OpenFont("trzcionki/arial.ttf",12); //TRZCIONKA
    SDL_Color kolor={0,0,0};
    tekst.powierzchnia = TTF_RenderText_Blended(arial,"60 FPS", kolor);
        int posX(100);// pozycja postaci
        int posY(385);//
        while(frame==0)
        { // petla while frame 0
                {// fps poczatek
                    fps.start();
                }
                {//render
        tlo.blitSU(ekran);
        chmura1.blitSU(ekran);
        chmura2.blitSU(ekran);
        chmura3.blitSU(ekran);
        postac.zmien_koordynaty(posX,posY);
        postac.blitSU(ekran);
        tekst.blitSU(ekran);
        gorna_BAR.blitSU(ekran);
        dolna_BAR.blitSU(ekran);
        if(tryb_test==true)
        {
        stringstream konwersja;
        konwersja << "x= " << posX << ", y= " << posY;
        pozycje.powierzchnia = TTF_RenderText_Solid(arial,konwersja.str().c_str(), kolor);
        pozycje.blitSU(ekran);
        }

                }
                { //wydarzenia
                wydarzenia();

                }
                {//odswiezanie
            SDL_UpdateWindowSurface(okno);
                }
                {//sterowanie
                    {//wyjscie
                wyjscie();
                    }
                            {//poruszanie sie lewo prawo
            if(GetAsyncKeyState(0x41))//lewo
            {
                if(posX!=-10) posX-=5;
            }
           {//poruszanie sie w prawo
           {
              if(GetAsyncKeyState(0x44)) if(posX!=780) posX+=5;
           }
           }
           {//skoki
              using namespace pif;

     if(GetAsyncKeyState(0x57)&&w_locie==0&&w_locie_z_shiftem==0) // gora
           {
              if(posY!=-5&&posY==530) {posY-=10; latanie++; w_locie=1; }
           }
           if(GetAsyncKeyState(0x57)&&GetAsyncKeyState(0x10)) // gora z shiftem
           {
              if(posY!=-5&&posY==530&&latanie==0) {posY-=15; latanie++; w_locie=0; w_locie_z_shiftem=1; }
           }

           {//zaleznosci jak kto woli wydarzenia typu jest na ziemi itp


               {//opadanie
                   if(postac.kolizja(dolna_BAR)==false) posY+=1;  //opadanie
               }


           if(postac.kolizja(dolna_BAR)==true) {latanie=0; w_locie=0; w_locie_z_shiftem=0;}
           }

           if(w_locie==1&&latanie!=30)
           {
              posY-=5; latanie++;

           }
           if(w_locie_z_shiftem==1&&latanie!=25) {posY-=10; latanie++;}


           {//error
               if(w_locie==1&&w_locie_z_shiftem==1) error(okno,ekran);
           }
           }
                            }
                }

                {// fps koniec
                    fps.koniec();
                }

}
}

licznik.cpp

#include<iostream>
#include<fstream>
#include"licznik.h"
#include<sstream>
#include<string>
#include<iomanip>
using namespace std;
const char * licznik()
{
    const string nazwa("wersja.txt");
    fstream strumien;
    stringstream konwersja;
    strumien.open(nazwa.c_str(),ios::out|ios::in|ios::app);
    int liczba(0);
    strumien.seekg(ios::cur-1);
    strumien >> liczba;
    double wersja=liczba/1000.0;
    strumien.close();
    strumien.open(nazwa.c_str(),ios::out|ios::in|ios::trunc);
    liczba++;
    strumien << liczba;
    strumien.close();
    konwersja << "SDL_Test "<< fixed << setprecision(2) << wersja;
    string k(konwersja.str());
    return k.c_str();
}


parametry.cpp

namespace pif//parametry i flagi
{
    static short int latanie=0;
    static short int w_locie=0;
    static short int w_locie_z_shiftem=0;
    static short int podloze=0;
    /********************************************************************/
         bool mozna_gora=0;
         bool mozna_dol=0; ///
         bool mozna_lewo=0; /// flagi czy mozna w gore w dol etc
         bool mozna_prawo=0;
    /********************************************************************/
    class pifmanip
{
    public:
        pifmanip() {mozna_dol=0;mozna_gora=0;mozna_lewo=0;mozna_prawo=0;latanie=0;w_locie=0;podloze=0;w_locie_z_shiftem=0;}
    /********************************************************************/
    static void stop_gora()
    {mozna_gora=0;}
    static void stop_dol()
    {mozna_dol=0;}///
    static void stop_lewo()
    {mozna_lewo=0;}/// funkcje zmieniajace neg
    static void stop_prawo()
    {mozna_prawo=0;}
    /********************************************************************/
    static void start_gora()
    {mozna_gora=1;}
    static void start_dol()
    {mozna_dol=1;}///
    static void start_lewo()
    {mozna_lewo=1;}/// funkcje zmieniajace poz
    static void start_prawo()
    {mozna_prawo=1;}
    /********************************************************************/
};
}

wydarzenia.cpp


#include"wydarzenia.h"
#include<SDL2/SDL.h>
#include<cstdlib>

void wydarzenia()
{
    SDL_Event zdarzenie;
    wyj_Quit(zdarzenie);
}

wyj_Quit.cpp

#include "wydarzenia.h"
#include <cstdlib>
#include <SDL2/SDL.h>
void wyj_Quit(SDL_Event &z)
{
    while(SDL_PollEvent(&z))
              {
                    if(z.type==SDL_QUIT)
                    {
                  exit(0);
                    }
              }
}

wyjscie.cpp

#include"funkcje_sterowania.h"
#include<windows.h>
void wyjscie()
{
    if(GetAsyncKeyState(0x1B))//wyjscie pod ESC
           {
               exit(0);
           }
}

P.S. Przepraszam za podanie całego kodu, ale na innym forum cały czas kazali podać więcej kodu(a i tak problemu nie rozwiązali).

1 odpowiedź

+1 głos
odpowiedź 25 lipca 2016 przez MetRiko Nałogowiec (37,110 p.)
wybrane 25 lipca 2016 przez Bot
 
Najlepsza

Problem "first defined here" pojawia się, gdy (jak sama nazwa wskazuje) coś zostało zdefiniowane więcej niż raz.. np. funkcja, bądź klasa (nie mylić z deklaracją!). Prawdopodobnie (jak nie na 100%) przez stawianie takiej ściany include'ów w plikach nagłówkowych (.h) gdzieś, któryś "tworzy" w kodzie dwa razy ten sam element (w tym wypadku podejrzewam, że chodzi o funkcję). Innymi słowy staraj się używać jak najmniej dyrektywy include w plikach nagłówkowych, a jeżeli potrzebujesz konkretnej klasy z innego pliku zastosuj tzw. "forward declaration".
Prosty przykład:
Wersja bez "include'ów" na cpp.sh: http://cpp.sh/3wku (możesz odpalić.. działa bez problemu)

//Plik: Object.h

class Manager; //Tutaj deklarujesz klasę Manager (mówisz kompilatorowi, że klasa Manager istnieje w tym kodzie, ale jej ciało jest w innym miejscu)
class Object
{
    int a;
    const Manager *ptr_Manager;
public:
    void SetValue(int NewValue);
    void SetManager(const Manager *NewManager);
    int GetValue();
};

//Plik: Manager.h

class Object; //Tutaj deklarujesz klasę Object (podobnie jak z klasą Manager)
class Manager
{
    Object *Obj;
public:
    void SetObject(Object &NewObject, int NewValue);
};

//Plik: Manager.cpp

#include <Manager.h>
#include <Object.h> //Tutaj już TRZEBA dołączyć plik Object.h ponieważ będzie potrzebne nam jej ciało (np. funkcja SetValue)

void Manager::SetObject(Object &NewObject, int NewValue)
{
    Obj=&NewObject;
    Obj->SetManager(this);
    Obj->SetValue(NewValue);
}

//Plik: Object.cpp

#include <Object.h>
#include <Manager.h>

void Object::SetValue(int NewValue)
{
    a=NewValue;
}

void Object::SetManager(const Manager *NewManager)
{
    ptr_Manager=NewManager;
}

int Object::GetValue()
{
    return a;
}

//Plik: main.cpp

#include <Object.h>
#include <Manager.h>

#include <iostream>

int main()
{
    Manager Mng;
    Object Obj_1, Obj_2;
    
    Mng.SetObject(Obj_1, 100);    
    Mng.SetObject(Obj_2, 200);    
    
    std::cout<<"Value in first object: "<<Obj_1.GetValue()<<"\nValue in second object: "<<Obj_2.GetValue();
}

 

komentarz 25 lipca 2016 przez Bot Użytkownik (760 p.)
Dziękuje!

Nie miałem nigdy okazji dowiedzieć się o czymś takim jak forward declaration. Dzięki za komentarze chociaż niektóre są zbędne.
komentarz 25 lipca 2016 przez MetRiko Nałogowiec (37,110 p.)
Nigdy nie wiem z kim mam do czynienia dlatego lepiej gdy jest więcej komentarzy niż by miało być coś niezrozumiałe x) Poza tym możliwe, że będę korzystał z tego posta gdy ktoś będzie miał podobny problem (po co pisać coś dwa razy).
komentarz 25 lipca 2016 przez Bot Użytkownik (760 p.)
ok tylko ja nadal tg przykładu nie zrozumiałem - rozumiem cały podany przez cb kod tylko on nie rozwiązuje problemu

żadnego include w ten sposób nie omine

może że chodzi o to:

masz main w którym jest tylko include jednego naglowkowego pliku

korzystasz z funkcji, które zawierają kolejne funkcje i każda funkcja ma swoje potrzebne tylko jej include?
komentarz 25 lipca 2016 przez Bot Użytkownik (760 p.)
na tym to polega?
komentarz 25 lipca 2016 przez MetRiko Nałogowiec (37,110 p.)
Chodzi o to, aby odpowiednio rozdzielić kod na pojedyncze pliki.. uściślając.. wszystkie include'y (twojej roboty, nie zaliczam do tego SDL, albo iostream) zamień na forward declaration.. coś w stylu:
#include "framy.h" -> class frame;
#include "licznik.h" -> class licznik;
#include "obiect.h" -> class obiect; //Tak poza tym to pisze się object, albo obiekt.. to jest jakieś dziwne angielsko-polskie połączenie ;D
Oczywiście wszystkie definicje funkcji muszą się znajdować w plikach .cpp, a nie w .h, a z tego co widziałem to są u ciebie sytuacje, gdzie ta zasada (z jakiegoś powodu) nie jest przestrzegana.. może jest to wygodniejsze.. ale bardzo nieeleganckie i poza tym potrafi sprawić, że kod się nie skompiluje.
komentarz 26 lipca 2016 przez Bot Użytkownik (760 p.)
Obecnie kod jest większy a nazwy to obiekt.h i obiekt.cpp a sama w sobie klasa nazywa się obiekt

Podobne pytania

+1 głos
6 odpowiedzi 24,426 wizyt
–1 głos
0 odpowiedzi 1,135 wizyt
0 głosów
1 odpowiedź 289 wizyt
pytanie zadane 26 stycznia 2020 w C i C++ przez Nowicjusz13 Użytkownik (570 p.)

92,576 zapytań

141,426 odpowiedzi

319,652 komentarzy

61,961 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...