2013-08-20 60 views
1

我完全不確定爲什麼我在運行我的程序時遇到VS2012中的此錯誤。 Visual Studio中似乎在0x777122D2(ntdll.dll中)在ArticxEngine.exe引向sf::RenderWindow Articx::window;的問題Articx.cppArticxEngine.exe中的0x777122D2(ntdll.dll)未處理的異常:0xC0000005:訪問衝突寫入位置0x00000004

未處理的異常: 0000005:訪問衝突寫入位置0x00000004。

代碼Articx.h

#pragma once 

#include <SFML/Graphics.hpp> 
#include <SFML/Window.hpp> 

class Articx 
{ 
    public: 
     static void Start(); 
    private: 
     static void GameLoop(); 

     static bool isExiting(); 

     enum ScreenState {before, splash1, splash2, splash3, menu, pause, playing, exit}; 
     static ScreenState currentState; 

     static sf::RenderWindow window; 
}; 

代碼Articx.cpp

#include <SFML/Graphics.hpp> 
#include <SFML/System.hpp> 
#include <SFML/Window.hpp> 
#include <iostream> 
#include <string> 
#include "Articx.h" 

inline void Message(char message[]); 
inline void CallError(int code, char message[]); 

Articx::ScreenState Articx::currentState = Articx::before; 
sf::RenderWindow Articx::window; 

void Articx::Start() 
{ 
    Message("Articx Engine 1.0 Initializing..."); 

    if(currentState != before) 
     return; 

    window.create(sf::VideoMode(800,600,32), "Articx Engine 1.0"); 
    currentState = playing; 

    while (!isExiting()) 
    { 
     Message("Engine Initialized"); 
     Articx::GameLoop(); 
    } 

    window.close(); 
} 

bool Articx::isExiting() 
{ 
    if(currentState == exit) 
     return true; 
    else 
     return false; 
} 

void Articx::GameLoop() 
{ 
    sf::Event currentEvent; 

    while (window.pollEvent(currentEvent)) 
    { 
     switch(currentState) 
     { 
      case Articx::playing: 
       { 
        window.clear(sf::Color(0,0,0)); 
        window.display(); 

        if (currentEvent.type == sf::Event::Closed) 
         currentState = exit; 
        break; 
       } 
     } 
    } 

    window.display(); 
} 

inline void CallError(int code, char message[]) 
{ 
    std::cout << "ERROR CODE - " << code << std::endl << message << std::endl << "Will now exit..." << std::endl; 
    system("PAUSE"); 
} 

inline void Message(char message[]) 
{ 
    std::cout << "AX-MESSAGE: " << message << std::endl; 
} 

代碼main.cpp

#include "Articx.h" 

using namespace std; 

int main(int argc, char** argv) 
{ 
    Articx::Start(); 
    return 0; 
} 

回答

6

「底線」 原因

未處理的異常的原因是因爲您將Articx :: window定義爲靜態變量。

技術說明

異常被拋出,因爲構建SF:RenderWindow的調用下面的構造順序如下:

RenderWindow的:: RenderWindow的()
窗口::窗口( )
GlResource :: GlResource()

T他GlResource :: GlResource()構造函數試圖鎖定一個全局mutex:

namespace 
{ 
    // OpenGL resources counter and its mutex 
    unsigned int count = 0; 
    sf::Mutex mutex; 
} 


namespace sf 
{ 
//////////////////////////////////////////////////////////// 
GlResource::GlResource() 
{ 
    { 
     // Protect from concurrent access 
     Lock lock(mutex); 

     // If this is the very first resource, trigger the global context initialization 
     if (count == 0) 
      priv::GlContext::globalInit(); 

     // Increment the resources counter 
     count++; 
    } 

    // Now make sure that there is an active OpenGL context in the current thread 
    priv::GlContext::ensureContext(); 
} 

的問題是,無論你Articx ::窗口和SFML的SF ::互斥互斥是全局/靜態變量是在程序初始化時構建。哪一個先構建?在你的情況下,你的窗口首先被構造,所以GlResource :: GlResource()構造函數試圖鎖定一個無效的sf :: Mutex。由於全局/靜態變量的構造順序可能無法預測,因此最好在非全局位置創建sf :: RenderWindow對象。

解決方案

在main.cpp中,創建內的main()前面的sf :: RenderWindow的對象,通過Articx ::開始()傳遞一個參考窗口

#include "Articx.h" 

using namespace std; 

int main(int argc, char** argv) 
{ 
    sf::RenderWindow window; 

    Articx::Start(window); 
    return 0; 
} 

在Articx。小時,除去靜態成員變量窗口,擴大啓動()Gameloop()接受的SF :: RenderWindow的參考:

#pragma once 

#include <SFML/Graphics.hpp> 
#include <SFML/Window.hpp> 

class Articx 
{ 
    public: 
     static void Start(sf::RenderWindow &window); 
    private: 
     static void GameLoop(sf::RenderWindow &window); 

     static bool isExiting(); 

     enum ScreenState {before, splash1, splash2, splash3, menu, pause, playing, exit}; 
     static ScreenState currentState; 
}; 

在Articx.cpp,取出的全局定義窗口和修改開始()Gameloop()接受並使用通過SF :: RenderWindow的參考:

void Articx::Start(sf::RenderWindow &window) 
{ 
    Message("Articx Engine 1.0 Initializing..."); 

    if(currentState != before) 
     return; 

    window.create(sf::VideoMode(800,600,32), "Articx Engine 1.0"); 
    currentState = playing; 

    while (!isExiting()) 
    { 
     Message("Engine Initialized"); 
     Articx::GameLoop(window); 
    } 

    window.close(); 
} 

. . . 

void Articx::GameLoop(sf::RenderWindow &window) 
{ 
    . . . 
} 

現在運行它正確顯示窗口:

enter image description here

窗口似乎有無限循環打印「引擎初始化」,但我留給你:-)。

+0

非常感謝你!從來沒有想過它。在我只是SFML的初學者之前,我已經看到過這樣的問題,我從來沒有發現過這種衝突。 – freemann098

+0

我也很容易修復無盡的消息循環。 :) – freemann098

相關問題