Referință nedefinită la "SDL_main"

Recent am decis sa incerc sa lucrez cu SDL cu CodeBlocks 10.05. Am inceput cu tutorialul pe http://www.sdltutorials.com/sdl-tutorial-basics

..\..\..\..\..\..\SDL\SDL-1.2.15\lib\libSDLmain.a(SDL_win32_main.o):SDL_win32_main.c|| undefined reference to `SDL_main'|

când încerc să compilez.

Am căutat multe dintre întrebările de pe acest site și alte tutoriale (în special tutorialul pe LazyFoo și wiki-ul CodeBlocks) și nu pot găsi o soluție.

  • C:\SDL\SDL-1.2.15\include has been added in the Compiler tab (Search Directories)
  • C:\SDL\SDL-1.2.15\lib has been added in the Linker tab
  • The libraries libmingw32.a, libSDLmain.a, libSDL.dll.a are linked in that order
    • libmingw32.a from the MinGW\lib folder in the CodeBlocks installation directory
  • SDL.dll is in both the System32 folder and in the project folder

Când am încercat să urmez tutorialul de pe wiki-ul CodeBlocks, mi sa spus că SDL.h nu a putut fi găsit în directorul dat (când faci un nou proiect SDL).

CApp.cpp

#include "CApp.h"
#include "SDL\SDL.h"

CApp::CApp(){
    Surf_Display=NULL;

    Running=true;
}

int CApp::OnExecute(){
    if (OnInit()==false){
        return -1;
}

SDL_Event Event;

while (Running){
    while (SDL_PollEvent(&Event)){
        OnEvent(&Event);
    }
    OnLoop();
    OnRender();
}

OnCleanup();
return 0;
}

int main(int argc, char* argv[]){
    CApp theApp;

    return theApp.OnExecute();
}

CApp.h

#ifndef CAPP_H_INCLUDED
#define CAPP_H_INCLUDED
#include "SDL\SDL.h"

class CApp{
    private:
        bool Running;
        SDL_Surface* Surf_Display;

    public:
        CApp();
        int OnExecute();

    public:
        bool OnInit();
        void OnEvent(SDL_Event* Event);
        void OnLoop();
        void OnRender();
        void OnCleanup();
};



#endif//CAPP_H_INCLUDED
0
@Musa Îmi pare rău, ai putea explica ce ai vrut să spui prin asta? Sunt relativ nou la programare și nu prea înțeleg. Are aceasta legătură cu setarea mea de SDL (Linking and whatnot) sau este o problemă în cadrul codului? Mulțumiri!
adăugat autor Prismriver, sursa
@jrok Tocmai am încercat să redobândesc toate legăturile după ce a indicat tutorialul, precum și punctele enumerate mai sus. Pentru a trece prin ceea ce am făcut: - Descărcat SDL-1.2.15-win32-x64.zip (Windows pe 64 de biți) și SDL-devel-1.2.15-mingw32.tar.gz (Mingw32) de pe site-ul SDL. - Extracționat primul în C: \ SDL și a plasat SDL.dll din al doilea în folderul proiectului și system32 - Adăugat \ include și \ lib în tab-ul compilatorului și linker-ul respectiv - Linked libmingw32.a, libSDLmain.a, și libSDL.dll.a în această ordine.
adăugat autor Prismriver, sursa
@jrok Am cu siguranță fișierele .a menționate mai sus în folderele lib. Există, de asemenea, versiuni ._ (de ex. "._libSDLmain.a", precum și "libSDLmain.a" corespunzătoare). Este extras chiar de la "SDL-devel-1.2.15-mingw32.tar.gz" disponibil pe site-ul SDL. Doresc doar să apăs F9 pentru a construi și a executa proiectul.
adăugat autor Prismriver, sursa
Nu contează, văd acest lucru în SDL_main.h
adăugat autor Musa, sursa
IIRC trebuie să furnizați SDL_main , în loc să aveți un principal aveți un SDL_main
adăugat autor Musa, sursa
Trebuie să lipsească ceva în configurarea linkerului. În felul în care l-ați descris, ar trebui să funcționeze (și într-adevăr, pentru mine cel puțin).
adăugat autor jrok, sursa
Dar ați verificat dacă * .a libs există într-unul din directoarele pe care linkerul le vede? Le puteți găsi în pachetul devel în directorul /lib .
adăugat autor jrok, sursa
Oh, și asigurați-vă că compilați de fapt CApp.cpp.
adăugat autor jrok, sursa

3 răspunsuri

Singurul motiv plauzibil al problemei la care mă pot gândi este că atunci când ați creat fișierul cu main în el, ați uitat să îl adăugați pentru a crea ținte.

enter image description here

Ar trebui să vedeți CApp.cpp în lista unde este main.cpp-ul meu. Faceți clic dreapta pe el și faceți clic pe Proprietăți. Faceți clic pe fila Construiți în fereastra care apare. Ar trebui să vedeți acest lucru:

enter image description here

Faceți clic pe OK, apăsați pe Ctrl + F11 (Rebuild).

Mult noroc.

0
adăugat
Mulțumesc mult! Nu pot să cred că asta a fost problema!
adăugat autor Prismriver, sursa
Se pare că este necesară această sintaxă/semnătura exactă pentru funcția principal . Dacă folosiți doar int main() {} ca multe suporturi pentru compilatoare, nu funcționează. Dacă cineva știe de ce, dați-mi voie să știu.
adăugat autor Jochem Kuijpers, sursa

Încercați #undef principal după toate anteturile legate de SDL.

Actualizare. Aceasta nu este o soluție validă!

Așa cum a subliniat HolyBlackCat, aceasta este o rezolvare destul de neclară. SDL înlocuiește funcția principală pentru a efectua inițializarea și/sau curățarea care altfel nu este posibilă și apoi apelează înapoi la funcția actuală a utilizatorului.

Interceptarea funcționează prin înlocuirea numelui funcției principale a utilizatorului cu SDL_main , cu o macrocomandă simplă

#define main SDL_main

Funcția utilizatorului apoi nu mai este punctul de intrare al aplicației și se utilizează un punct de intrare furnizat de SDL. Codul propus #undef dezactivează incapacitatea de a intercepta și ar trebui să susțină că nu ar trebui să funcționeze deloc. Pentru cei care au compilat cu succes și au executat o aplicație SDL după această "remediere", trebuie să fi fost pur și simplu o coincidență dependentă de platformă.

Soluția corectă a erorilor OP este să vă asigurați că fișierul care conține main este compilat și legat și că funcția are semnătura corectă. Așa cum deja au postat ceilalți.

0
adăugat
Totuși, aceeași problemă după ce ați încercat acest lucru.
adăugat autor Prismriver, sursa
da, acest lucru a lucrat prea pe Windows
adăugat autor Kokizzu, sursa
Chiar dacă pare să funcționeze, nu ar trebui să o facem. SDL are #define SDL_main principal , deoarece trebuie să facă o inițializare în main() înainte de a executa codul de utilizator. Poate sau nu poate să funcționeze dacă opriți această inițializare.
adăugat autor HolyBlackCat, sursa
Îmi pare rău că l-am păstrat atât de mult. Desigur, aceasta nu este o soluție corectă. Mi-am dat seama de mult și vroiam să scriu o actualizare, dar nu am avut timp să dezvolt înțelegerea deplină a problemei și de ce funcționează "soluția" mea.
adăugat autor Marcin Kaczmarek, sursa
VREAȚI JUCĂRILE ... Îmi doresc să fi găsit asta cu o oră mai devreme. Lucrat pe OSX.
adăugat autor nevelis, sursa
De ce rezolva problema?
adăugat autor zoran404, sursa

pune aceste argumente la funcția principală. Am avut și această problemă și am repetat-o ​​acum câteva secunde.

int main (int argv, char ** args) { }

0
adăugat
Mulțumiri! Oricine dorește/poate explica de ce funcționează acest lucru (@ vă rog)?
adăugat autor Jochem Kuijpers, sursa
@JochemKuijpers această semnătură specială este necesară, deoarece SDL modifică rezolvarea punctului de intrare implicit al programului. În condiții normale, puteți utiliza una din numeroasele semnături standard pentru funcția principală, int main() , void principal() **) , etc. Compilatorul va accepta toate aceste variante. Dar SDL interceptează punctul principal de intrare, așa cum este descris în răspunsul meu, și vă cheamă punctul de intrare așteptând o semnătură specifică, care nu mai este supusă interpretării compilatorului.
adăugat autor Marcin Kaczmarek, sursa
a lucrat pentru mine :)
adăugat autor Grzegorz Bazior, sursa
E magic. A lucrat pentru mine!
adăugat autor Tamarous, sursa