Hei, olen tässä aikani pähkäillyt miksi ihmeessä koodini ei toimi. Olen tehnyt ohjelmaani varten Menu-luokan jolla voi tehdä helposti pää- ja pause-valikot. Funktio jolla lisätään valinta valikkoon pyytää painikkeen kuvat ja osoittimen funktioon joka suoritetaan nappia painettaessa. Jostain syystä tulee tämän lainen virhe käännettäessä:
main.cpp:16:49: error: ‘Menuf’ was not declared in this scope
Koodi jota olen yrittänyt saada toimimaan: (main.cpp)
#include <SFML/Window.hpp> //Liitetään tarvittavat kirjastot #include <SFML/Graphics.hpp> #include "Menu.hpp" //Myös oma "Menu" luokka bool Menuf(void); //Esitellään funktio joka suoritetaan jos painiketta valikossa painetaan int main() { sf::Image redButton; //Ladataan painikkeen kuvat sf::Image greenButton; redButton.LoadFromFile("rb.png"); greenButton.LoadFromFile("gb.png"); sf::RenderWindow App(sf::VideoMode(800, 600, 32), "Scape War"); //Avataan ikkuna const sf::Input& Input = App.GetInput(); Menu MainMenu(true); //Luodaat valikko MainMenu.add_button(redButton, greenButton, Menuf); //Lisätään painike while (App.IsOpened()) { sf::Event Event; while (App.GetEvent(Event)) //Käydään kaikki tapahtumat läpi { if (Event.Type == sf::Event::Closed) //Suljetaan jos käyttäjä tahtoo App.Close(); if ((Event.Type == sf::Event::KeyPressed) && (Event.Key.Code == sf::Key::Escape)) //ESC:istäkin voi poistua App.Close(); } MainMenu.update(&App, 800, 600); //Päivitetään valikko ruudulle App.Display(); //Päivitetään ruutu } return EXIT_SUCCESS; } bool Menuf(void) { //Tässä sisältöä tälle funktiolle return true; //Eli ei tee juuri mitään. }
Kerrotko vielä miksi Menuf-funktio on kirjoitettu? Sehän ei oman kuvauksesi mukaankaan tee mitään.
Katsoitko edes virheen rivinumeroa? Ei se taida tuossa koodissa olla vaan Menu.hpp:ssä. Sieltähän et voi Menuf-funktioon tuolla nimellä suoraan viitata.
Joo viheen rivinumero tosta unohtuikin(päivitin ekaan viestiin). Kyllä, se näyttää olevan tossa tiedostossa(main.cpp), tuossa kohdassa missä se annetaan parametriksi Menu-luokan funktiolle. Menuf funktio on testaamista varten, halusin testata Menu-luokan toimintaa. Peli on vasta niin alussa että sen ei ole tarkoitus tehdä mitään muuta, kuin näytää valikko. Jonkin lainen funktio oli kyhättävä, koska sitä parametriksi tarvitaan. En ole yrittänyt Menuf-funktioon viitata muissa tiedostoissa.
Siis tuolla rivillä 16 annat funktion parametrina? Ehkä tarkoitat lähettää sen paluuarvon, kirjoita sulkeet perään. Nythän siinä lukee vain "Menuf", kirjoita "Menuf()".
Jos ohjelmassa kutsuttaisiin Menuf:ää normaalisti ("Menuf();") tulee yhä tuo virheilmoitus. :/ Siis tarkoitus on että tuo Menu-luokka voi milloin haluaa kutsua sille parametrina annetun funktio-osoittimen kautta Mainf funktiota.
Menu.hpp:ssä tuo funktio jolle funktio-osoitin halutaan antaa on esitelty seuraavati:
int add_button(sf::Image img, void (*onClick)(void)); int add_button(sf::Image img, sf::Image img2, void (*onClick)(void));
ja Menu.cpp:ssä:
int Menu::add_button(sf::Image img, void (*onClick)(void)){ ButtonImage.push_back(img); ButtonImage2.push_back(img); ButtonFunction.push_back(*onClick); ButtonMode.push_back(0); } int Menu::add_button(sf::Image img, sf::Image img2, void (*onClick)(void)){ ButtonImage.push_back(img); ButtonImage2.push_back(img2); ButtonFunction.push_back(*onClick); ButtonMode.push_back(0); }
Joo, mutta eihän tuossa rivillä 16 mitään funktio-osoitinta lähetetä? Sanokaa, jos olen väärässä, mutta minusta nyt näyttää siltä. Eikös funktio-osoitin pitäisi luoda erikseen? Minusta näyttää, että kirjoitat vain funktion nimen ilman sulkeita. Tee funktio-osoitin, joka osoittaa Menuf-funktioon ja lähetä se add_buttonille. Tämän enempää en osaa nyt auttaa :)
Funktiosi paluuarvo on bool, se ei siis sovi tuohon parametriin. Ja vesikuusi on väärässä, osoitin menee juuri noin.
Parametrilistan paikalla oleva void on turha tässä kielessä.
Aivan, itse en tota huomannutkaan! Kiitti Metabolix, opin taas jotain uutta :D
Korjasin Menuf-funktion näin:
void Menuf(){ return; }
Ja tulee virheilmoituksia:
Menu.hpp:9:1: error: new types may not be defined in a return type Menu.hpp:9:1: note: (perhaps a semicolon is missing after the definition of ‘Menu’) main.cpp:5:12: error: two or more data types in declaration of ‘Menuf’ main.cpp: In function ‘int main()’: main.cpp:18:49: error: ‘Menuf’ was not declared in this sc
Menu.hpp kokonaisuudessaan:
#include <SFML/Window.hpp> #include <SFML/Graphics.hpp> #include <vector> #ifndef _MENU_HPP #define _MENU_HPP 1 typedef void (*IPF)(); class Menu{ public: Menu(bool parrow_keys); int add_button(sf::Image img, void (*onClick)()); int add_button(sf::Image img, sf::Image img2, void (*onClick)()); int get_button_mode(int button_no); void update(sf::RenderWindow*, int, int); private: std::vector <sf::Image> ButtonImage; std::vector <sf::Image> ButtonImage2; std::vector <int> ButtonMode; std::vector <IPF> ButtonFunction; bool arrow_keys; } #endif
ja Menu.cpp:
#include "Menu.hpp" #include <SFML/Window.hpp> #include <SFML/Graphics.hpp> #include <vector> Menu::Menu(bool parrow_keys){ arrow_keys = parrow_keys } int Menu::add_button(sf::Image img, void (*onClick)(void)){ ButtonImage.push_back(img); ButtonImage2.push_back(img); ButtonFunction.push_back(*onClick); ButtonMode.push_back(0); } int Menu::add_button(sf::Image img, sf::Image img2, void (*onClick)()){ ButtonImage.push_back(img); ButtonImage2.push_back(img2); ButtonFunction.push_back(*onClick); ButtonMode.push_back(0); } int Menu::get_button_mode(int button_no){ return ButtonMode[button_no]; } void Menu::update(sf::RenderWindow* app, int w, int h){ sf:Sprite button; sf:Input& Input = app.GetInput(); int mouseX = Input.GetMouseX(); int mouseY = Input.GetMouseY(); for(int i = 0; i < ButtonMode.size(); i++){ if(ButtonMode[i] == 0){ button.Set_Image(ButtonImage[i]); } else if(ButtonMode[i] == 1){ button.Set_Image(ButtonImage1[i]); } button.SetX(w/2-button.GetImage().GetWidth()/2); int yhtl = 0; for(int ii = 0; ii < ButtonMode.size(); ii++){ yhtl = yhtl + ButtonImage[i].GetHeight(); } button.SetY(h/ButtonMode.size()-yhtl/ButtonMode.size()); if(mouseX > w/2-button.GetImage().GetWidth()/2 and mouseX < w/2-button.GetImage().GetWidth()/2+button.GetImage().GetWidth()){ if(mouseY > h/ButtonMode.size()-yhtl/ButtonMode.size() and mouseY < h/ButtonMode.size()-yhtl/ButtonMode.size()+button.GetImage().GetHeight()){ ButtonMode[i] = 1 if(Input.IsMouseButtonDown(sf::Mouse::Right);) ButtonFunction[i](); } else{ ButtonMode[i] = 0 } } else{ ButtonMode[i] = 0 } app.Draw(button); } }
Menu.hpp:n riviltä 22 puuttuu puolipiste sulkevan aaltosulun jälkeen, aivan kuten virheilmoitus vihjaa. Tämä selittää myös miksi Menuf-funktiota ei löydy.
/tmp/ccsT4lpt.o: In function `main': main.cpp:(.text+0x210): undefined reference to `Menu::Menu(bool)' main.cpp:(.text+0x271): undefined reference to `Menu::add_button(sf::Image, sf::Image, void (*)())' main.cpp:(.text+0x313): undefined reference to `Menu::update(sf::RenderWindow*, int, int)' collect2: ld returned 1 exit status
Mitäs nyt? Ensimmäinen ohjelma jota yritän linux koneella saada aikaiseksi niin on vähän ongelmia, kun komentoriviltä pitää kääntää ja muuta. .o on ilmeisesti vastaava kuin .dll?
Nyt et ole kääntänyt kuin yhden tiedoston. Ei siitä kokonaista ohjelmaa synny. Asialla ei myöskään ole mitään tekemistä dll:n tai Linuxin vastaavan (so:n) kanssa.
Voit kääntää kaikki cpp-tiedostot kerralla, tai voit kääntää kunkin cpp-tiedoston erikseen ja linkittää objektit lopuksi yhteen.
g++ a.cpp b.cpp -o ohjelma # Tai: g++ *.cpp -o ohjelma
g++ -c a.cpp -o a.cpp.o g++ -c b.cpp -o b.cpp.o g++ a.cpp.o b.cpp.o -o ohjelma
Jälkimmäisen tavan etuna on, että ei tarvitse kääntää aina uudestaan kaikkia tiedostoja vaan vain muuttuneet. Automaattista käännöstä varten voit tehdä Makefilen, joka sisältää listan tiedostoista ja yleiset säännöt niiden käsittelyyn.
Sain käännettyä, mutta nyt kun ajan ohjelman ja se näyttää tältä: http://img193.imageshack.us/img193/8872/
Tuo "nappi" menee joka suoritus kerralla huonommaksi ja vaihtaa paikkaa.
(Mod. huom: Kannattaa vähän katsoakin, mitä niistä muotoilun apunapeista viestiin tulee. Suora linkki ei vaadi tageja.)
Aihe on jo aika vanha, joten et voi enää vastata siihen.