【问题标题】:Program crash when ported to windows移植到windows时程序崩溃
【发布时间】:2013-02-26 13:49:46
【问题描述】:

正如标题所说,我已经在 Linux Mint 14 上成功编译、链接并运行了一个用 sfml-1.6 制作的程序。我使用 g++ 进行编译。但是,一旦我将源文件移动到 Windows 并尝试编译为 sfml 库的 Windows 等效项,它就会崩溃。该程序可以正常编译和链接,但是在到达 main 之前就崩溃了。我确保我自己的 .h 文件中没有任何全局对象/变量。但我不能为 sfml 库做到这一点。我怀疑可能是因为库坏了,所以我移植了 sfml 2.0 的代码,问题仍然存在。关于我做错了什么的任何线索?我还确保我不使用任何特定于平台的标头。

这是我的 main.cpp

#include <SFML/System.hpp>
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include "World.h"
#include <sstream>
#include <vector>
#include <zip.h>

enum states
{
    MENU,
    GAME,
    PAUSE,
    EXIT,
    DIE
};
player plr;
sf::Clock timer;
void getKeys(const sf::Input& input);
std::string floatToString(float flt);

int main(int argc, char** argv) 
{
    sf::RenderWindow window(sf::VideoMode(1024, 768), "sfTest");
    window.SetFramerateLimit(60);
    sf::Music startSong;
    sf::Music endSong;
    sf::Music s1, s2, s3;
    sf::String musicBy;
    musicBy.SetText("Music by Kevin McLeod: www.incompetech.com");
    if(!s1.OpenFromFile("Batty McFaddin.ogg"))
        return -1;
    if(!s2.OpenFromFile("Merry Go.ogg"))
        return -1;
    if(!s3.OpenFromFile("One-eyed Maestro.ogg"))
        return -1;
    if(!endSong.OpenFromFile("One-eyed Maestro.ogg"))
        return -10;


    if(!startSong.OpenFromFile("Comedic Juggernaut.ogg"))
        return -15;

    endSong.SetVolume(50);

    std::vector<sf::Music*> playList;
    std::vector<sf::Music*>::iterator mIt;
    s1.SetVolume(25);
    s2.SetVolume(25);
    s3.SetVolume(25);
    playList.push_back(&s2);
    playList.push_back(&s3);
    playList.push_back(&s1);    

    startSong.SetLoop(true);
    startSong.SetVolume(50);
    const sf::Input& input = window.GetInput();

    plr.setSpeed(.5);
    plr.setMaxSpeed(15.0);
    plr.setJumpForce(.4f);
    plr.setJumpSpeed(16.f);

    int state = MENU;
    sf::String str;
    str.SetText("Welcome to fatrunning!");
    sf::String str2;
    str2.SetText("Developed by Echoes Entertainment");
    str2.Move(0, 100);
    sf::String cont;
    cont.SetText("Please press enter to play...");
    cont.Move(0, 30);
    sf::String spd;

    sf::String menuHelp;
    menuHelp.SetText("Stand on the block equivalent to the level (0-15) and press TAB");
    menuHelp.Move(0, 30);
    float endTime = 60*5;
    float curTime = 0;

    sf::Sprite menu;
    sf::Image mim;
    mim.LoadFromFile("MenuBackground.png");
    menu.SetImage(mim);

    sf::String scr;
    sf::String thanks("Thanks for playing! Your score was: ");
    //sf::String tarantulas("                             Tarantual tarantulas         Everybody loves tarantulas         if there's just fuzz where your hamster was         it's propably because of tarantulas                                             They're so soft         and they're so furry         And they're so cute         if your vision's blurry         all of mine got free         but dont you worry         though they're crawling up your wall in a big hurry                                    Tarantual tarantulas         Everybody loves tarantulas         if there's just fuzz where your hamster was         it's propably because of tarantulas                                             Don't look now but i have a feeling         there's one above you on your ceiling         but when they crawl they never fall                 unless the person under them is nervous at all                            Tarantual tarantulas           Everybody loves tarantulas         if there's just fuzz where your hamster was             it's propably because of tarantulas                 \t        \t                   can you feel that itch   on the top of your head         it could be one of them crawling instead         but it wont bite unless it senses fear         so just stay calm til' it's gone in a year                \t\t                              Tarantual tarantulas            Everybody loves tarantulas         if there's just fuzz where your hamster was         it's propably because of tarantulas          Tarantual tarantulas         Everybody loves tarantulas         if there's just fuzz where your hamster was         it's propably because of tarantulas         if there's just fuzz where your hamster was         it's propably because of tarantulas          Tarantulas tarantulas         it's propably because of tarantulas");
    //.tarantulas.Move(3000, 0);
    thanks.Move(0, 30);
    scr.Move(500, 30);

    World world;
    world.addLevel("lvl1", "lvl1.txt");
    world.addLevel("lvl2", "lvl2.txt");
    world.addLevel("lvl3", "lvl3.txt");
    world.addLevel("lvl4", "lvl4.txt");
    world.addLevel("lvl5", "lvl5.txt");
    world.addLevel("lvl6", "lvl6.txt");
    world.addLevel("lvl7", "lvl7.txt");
    world.addLevel("lvl8", "lvl8.txt");
    world.addLevel("lvl9", "lvl9.txt");
    world.addLevel("lvl10", "lvl10.txt");
    world.addLevel("lvl11", "lvl11.txt");
    world.addLevel("lvl12", "lvl12.txt");
    world.addLevel("lvl13", "lvl13.txt");
    world.addLevel("lvl14", "lvl14.txt");
    world.addLevel("lvl15", "lvl15.txt");
    world.setMenuLevel("menu.txt");
    world.regPlr(plr);
    bool once = false;
    bool unodos = false;
    float finalScore = 0;

    while (state != DIE) 
    {
        sf::Event e;
        while (window.GetEvent(e))
        {
            if ( e.Type == sf::Event::Closed )
            {
                window.Close();
                state = EXIT;
            }
            if( e.Type == sf::Event::KeyPressed )
            {
                if(e.Key.Code == sf::Key::Return)
                {
                    if(!unodos)
                    {
                        state = GAME;
                        unodos = true;
                    }
                }
            }
        }
        getKeys(input);
        window.Clear();
        switch(state)
        {
            case MENU:
                if(startSong.GetStatus() == sf::Sound::Stopped)
                    startSong.Play();
                window.Draw(menu);
                window.Draw(str);
                window.Draw(str2);
                window.Draw(cont);
                break;
            case GAME:
                if(startSong.GetStatus() == sf::Sound::Playing)
                {
                    mIt = playList.begin();
                    (*mIt)->Play();
                    startSong.Stop();
                }
                if((*mIt)->GetStatus() == sf::Sound::Stopped)
                {
                    mIt++;
                    if(mIt == playList.end())
                        mIt = playList.begin();
                    (*mIt)->Play();
                }
                timer.Reset();
                spd.SetText(floatToString(endTime-plr.time));
                world.drawWorld(window);
                world.update(input);
                plr.update();
                window.Draw(plr.getSprite());
                window.Draw(spd);
                plr.time+=timer.GetElapsedTime();
                if(plr.time >= endTime || world.quit)
                {
                    state = EXIT;
                    plr.time = endTime;
                }
                if(world.atMenu)
                    state = PAUSE;
                break;
            case PAUSE:
                if(startSong.GetStatus() == sf::Sound::Playing)
                    startSong.Stop();
                spd.SetText(floatToString(endTime-plr.time));
                plr.update();
                world.drawWorld(window);
                world.update(input);
                window.Draw(plr.getSprite());
                window.Draw(spd);
                window.Draw(menuHelp);
                if(!world.atMenu)
                    state = GAME;
                if(world.quit)
                    state = EXIT;
                break;
            case EXIT:
                if(!once)
                {
                    endSong.Play();
                    (*mIt)->Stop();
                    world.addLevel("end", "end.txt");
                    world.setLevel("end");
                    once = true;
                    finalScore = plr.score;
                    finalScore += (endTime-plr.time);
                }
                //tarantulas.Move(-3.5, 0);
                plr.update();
                world.drawWorld(window);
                window.Draw(plr.getSprite());
                scr.SetText(floatToString(finalScore));
                //window.Draw(tarantulas);
                window.Draw(musicBy);
                window.Draw(thanks);
                window.Draw(scr);
                if(world.curLvl->atEnd)
                    state = DIE;
                break;  
            case DIE:
                window.Close();
                break;
            default:
                break;
        }
        window.Display();
    }

    return 0;
}

std::string floatToString(float flt)
{
    std::stringstream ss;
    ss << flt;
    return ss.str();
}

void getKeys(const sf::Input& input)
{
    if(input.IsKeyDown(sf::Key::D))
    {
        plr.isAcc = true;
        plr.right();
    }           
    else if(input.IsKeyDown(sf::Key::A))
    {
        plr.isAcc = true;
        plr.left();
    }
    if(input.IsKeyDown(sf::Key::Space))
    {
        plr.isJump = false;
        plr.jump();
    }
    if(!input.IsKeyDown(sf::Key::D) && !input.IsKeyDown(sf::Key::A))
    {
        plr.isAcc = false;
    }
    if(!input.IsKeyDown(sf::Key::Space))
        plr.isJump = true;
}

这是整个main.cpp,如果您需要查看其他来源,请询问我。但是程序在到达 main 之前就崩溃了。它甚至没有达到枚举定义。

【问题讨论】:

  • 你有调用栈吗?它指向什么?
  • 你说它崩溃了。那是什么意思?收到错误信息?你是在调试器中运行的吗?
  • 当你说它崩溃时,它是抛出一个崩溃后错误还是类似的东西?
  • 它到底是在哪里崩溃的?您是否尝试过使用调试器?
  • main() 之前?您可能会发现这很有用:stackoverflow.com/q/335369/78845

标签: c++ linux windows porting sfml


【解决方案1】:

这可能是由于任何未定义或未指定的行为 具有静态生命周期的对象的构造函数。中的一个 然而,最常见的原因是初始化顺序 问题。将您的一些具有静态生命周期的对象使用其他对象 构造函数中具有静态生命周期的对象?例如, 播放器的构造函数是否使用中定义的静态对象 世界?或者甚至来自 SFML 的东西? (快速浏览显示一些 库中具有静态生命周期的对象。你不应该使用 任何带有静态的对象的构造函数中的任何一个 终生。)

【讨论】:

  • 当我想到它时,也许,我认为我有一个类可以解释另一个类的构造函数。我去看看
【解决方案2】:

在调试器 (windbg.exe) 中运行程序,它应该会向您显示异常发生的位置,在输出窗口中显示有用的进度文本,说明到目前为止已加载的内容,任何“被吞下”的异常,您可以接受它从那里开始。

【讨论】:

    【解决方案3】:

    崩溃可能是由于 EXE 的编译方式与库的编译方式之间存在一些不兼容...检查您的代码生成标志、字符集等。

    【讨论】:

    • 在 C++ 中,main() 之前的崩溃可能源自全局对象的构造函数。我会去那里看看。
    • 正如您在我的帖子中看到的,我没有全局对象。但是,我也尝试重新编译整个库以及使用已编译的库。
    • 如果不是全局对象是什么:player plr; sf::时钟定时器;
    • @user1935069:你确实说过,“我不能为 sfml 库做这件事”,所以即使你没有声明它们,假设你的程序在某处有全局对象也不是不公平的。例如,std::cin 是一个全局对象。但是,正如@J_D 指出的那样,plrtimer 是全局的 并且在您的代码 sn-p 中。恐怕你得再仔细看看。
    • 这个问题不是全球性的;这是静态生命周期。
    猜你喜欢
    • 2013-07-30
    • 2011-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多