[SOLVED!!] Access Violation while Subscribing to an Event

For help with general CEGUI usage:
- Questions about the usage of CEGUI and its features, if not explained in the documentation.
- Problems with the CMAKE configuration or problems occuring during the build process/compilation.
- Errors or unexpected behaviour.

Moderators: CEGUI MVP, CEGUI Team

Rackle
CEGUI Team (Retired)
Posts: 534
Joined: Mon Jan 16, 2006 11:59
Location: Montréal

Postby Rackle » Sun Feb 03, 2008 11:52

Sorry, my bad, I didn't think of the dependencies.

User avatar
CrazyEddie
CEGUI Project Lead
Posts: 6760
Joined: Wed Jan 12, 2005 12:06
Location: England
Contact:

Postby CrazyEddie » Sun Feb 03, 2008 15:25

Ok, the packages have been made available.

See this thread for the announcement.

CE.

Browser12
Not too shy to talk
Not too shy to talk
Posts: 42
Joined: Thu Jan 24, 2008 06:30
Location: UW-Madison
Contact:

Postby Browser12 » Sun Feb 03, 2008 20:39

First of all... awesome! :D So happy the 9.0 is out.
You guys really work hard on this... it's appreciated. ^^

So the part that gets me stuck right now is this..
my project builds fine with all the new stuff, but I crash here:

Code: Select all

CEGUI::OpenGLRenderer* Renderer = new CEGUI::OpenGLRenderer(0,640,480);


all it gives me is

Code: Select all

Unhandled exception at 0x7c812a5b in World Writer.exe: Microsoft C++ exception: CEGUI::GenericException at memory location 0x0012f1b0..


Is there some other syntax for the constructor of OpenGLRenderer now? The only examples I could find used this syntax.
I also couldn't find the CEGUI::OpenGLRenderer class in the .5.0 documentation. Seems like there's something I'm missing >>;

Rackle
CEGUI Team (Retired)
Posts: 534
Joined: Mon Jan 16, 2006 11:59
Location: Montréal

Postby Rackle » Mon Feb 04, 2008 01:41

The renderer is located within <cegui>\RendererModules\OpenGLGUIRenderer\openglrenderer.h. The syntax looks correct. You do not seem to catch the exception

Code: Select all

try
{
  CEGUI::OpenGLRenderer* Renderer = new CEGUI::OpenGLRenderer(0,640,480);
}
catch(Exception &e)
{
  #if defined( __WIN32__ ) || defined( _WIN32 )
    MessageBox(NULL, e.getMessage().c_str(), "Error initializing the demo", MB_OK | MB_ICONERROR | MB_TASKMODAL);
  #else
    std::cerr << "Error initializing the demo:" << e.getMessage().c_str() << "\n";
  #endif
}


Could there be a problem with the image codec? Within <cegui>\makefiles\premake\config.lua there's a section to control which image codecs are built and another to specify the default image code. Naturally you also need the relevant .dll within the executable's directory.

User avatar
CrazyEddie
CEGUI Project Lead
Posts: 6760
Joined: Wed Jan 12, 2005 12:06
Location: England
Contact:

Postby CrazyEddie » Mon Feb 04, 2008 08:54

Also, can you confirm whether you're using the SDK version or you're building the library yourself. By what you've been writing, I think you're using the SDKs, but just need to be sure.

I think Rackle has almost certainly identified the issue; the renderer can't find the image codec module. Btw, the new SDK defaults to SILLY for the codec - I'm not sure what the others were set to.

Browser12
Not too shy to talk
Not too shy to talk
Posts: 42
Joined: Thu Jan 24, 2008 06:30
Location: UW-Madison
Contact:

Postby Browser12 » Tue Feb 05, 2008 03:34

bah, i thought i'd responded, but i must have closed it or something. xDD
Sorry for the slow reply.

I am indeed using the SDK. I'm not really certain what exactly an image codec is (or SILLY), so I'm not entirely sure how to fix this...
I have both the renderer .dll (and the SILLY.dll, just now for good measure) in my executable directory.

Is there a quick way to fix this? :o

Thanks again :]

User avatar
CrazyEddie
CEGUI Project Lead
Posts: 6760
Joined: Wed Jan 12, 2005 12:06
Location: England
Contact:

Postby CrazyEddie » Tue Feb 05, 2008 04:50

Did you add the try/catch block as posted by Rackle? This would allow you to output the exception message and have a little more info to go on.

Having said this, I looked at some code and the only place I see CEGUI::GenericException being thrown is when SILLY fails to initialise (which shouldn't normally happen).

The dlls you need are CEGUIBase, SILLY, SILLYImageCodec, CEGUIExpatParser, CEGUIFalagardWRBase and OpenGLGuiRenderer. You also need the versions with the _d name suffix for running in debug mode.

To check things are working right, do the samples in the SDK run ok (the .exe files in the sdk/bin directory)?

Browser12
Not too shy to talk
Not too shy to talk
Posts: 42
Joined: Thu Jan 24, 2008 06:30
Location: UW-Madison
Contact:

Postby Browser12 » Tue Feb 05, 2008 05:01

Oh, awesome. That worked. I wasn't aware I needed all those .dll's.. I was just using a few of those.

Now I'm just getting directory-related problems that I usually get until I mess around with where stuff is:

Code: Select all

04/02/2008 22:58:37 (InfL1)   CEGUI::System singleton created.
04/02/2008 22:58:37 (InfL1)   ---- CEGUI System initialisation completed ----
04/02/2008 22:58:37 (InfL1)   ---- Version 0.5.1 ----
04/02/2008 22:58:37 (InfL1)   ---- Renderer module is: CEGUI::OpenGLRenderer - Official OpenGL based renderer module for CEGUI ----
04/02/2008 22:58:37 (InfL1)   ---- XML Parser module is: CEGUI::ExpatParser - Official expat based parser module for CEGUI ----
04/02/2008 22:58:37 (InfL1)   ---- Scripting module is: None ----
04/02/2008 22:58:37 (InfL1)   Attempting to load Scheme from file '../datafiles/schemes/WindowsLook.scheme'.
04/02/2008 22:58:37 (InfL1)   Attempting to create an Imageset from the information specified in file 'WindowsLook.imageset'.
04/02/2008 22:58:37 (Error)   Exception: DefaultResourceProvider::load - WindowsLook.imageset does not exist
04/02/2008 22:58:37 (Error)   Imageset::load - loading of Imageset from file 'WindowsLook.imageset' failed.


I just got this error, so I haven't really tried fixing it myself yet. Just thought I might's well post it since I'm replying anyways :]

But yeah, thanks for the help Eddie ^^

Rackle
CEGUI Team (Retired)
Posts: 534
Joined: Mon Jan 16, 2006 11:59
Location: Montréal

Postby Rackle » Tue Feb 05, 2008 11:53

The simplest approach is to use every .dll and the entire datafile directory structure that Cegui supplies and only start removing pieces once your application is completed. This approach will let you fully experience Cegui rather than having problems every time you want to use an advanced feature, and be blocked because you removed one item you thought you didn't need.

Browser12
Not too shy to talk
Not too shy to talk
Posts: 42
Joined: Thu Jan 24, 2008 06:30
Location: UW-Madison
Contact:

Postby Browser12 » Tue Feb 05, 2008 17:41

Well I just use the entire default datafiles structure.. just not .dll's (my executable directory is already pretty cluttered from .tga's and such.. so I try to only put in the .dll's that I'm going to use)
I can't figure out why the imageset is having troubles being found, though.
It finds the scheme, and I'm using the default structure with all the files and such. o__O

User avatar
CrazyEddie
CEGUI Project Lead
Posts: 6760
Joined: Wed Jan 12, 2005 12:06
Location: England
Contact:

Postby CrazyEddie » Tue Feb 05, 2008 19:12

Hey!

Resource handling changed a bit from 0.5.0 - and we dumped all those relative paths. Only trouble is nobody knows about it ;)

Try adding this to your CEGUI start up code, and then the supplied datafiles directory should work for you (this is the way it's set up in the samples framework):

Code: Select all

    // initialise the required dirs for the DefaultResourceProvider
    CEGUI::DefaultResourceProvider* rp = static_cast<CEGUI::DefaultResourceProvider*>
        (CEGUI::System::getSingleton().getResourceProvider());

rp->setResourceGroupDirectory("schemes", "../datafiles/schemes/");
rp->setResourceGroupDirectory("imagesets", "../datafiles/imagesets/");
rp->setResourceGroupDirectory("fonts", "../datafiles/fonts/");
rp->setResourceGroupDirectory("layouts", "../datafiles/layouts/");
rp->setResourceGroupDirectory("looknfeels", "../datafiles/looknfeel/");
rp->setResourceGroupDirectory("lua_scripts", "../datafiles/lua_scripts/");

// set the default resource groups to be used
CEGUI::Imageset::setDefaultResourceGroup("imagesets");
CEGUI::Font::setDefaultResourceGroup("fonts");
CEGUI::Scheme::setDefaultResourceGroup("schemes");
CEGUI::WidgetLookManager::setDefaultResourceGroup("looknfeels");
CEGUI::WindowManager::setDefaultResourceGroup("layouts");
CEGUI::ScriptModule::setDefaultResourceGroup("lua_scripts");


The above should also give you some hints should you decide to move the files around at any time (note that none of the files contain relative paths now, just the filenames).

I'll try to update all the beginners tutorials this coming weekend so they are relevant to the current code.

Sorry for the confusion :-P

CE.

Browser12
Not too shy to talk
Not too shy to talk
Posts: 42
Joined: Thu Jan 24, 2008 06:30
Location: UW-Madison
Contact:

Postby Browser12 » Tue Feb 05, 2008 19:39

[edit]:

Okay! So now I've got everything working! (yeay! :])
This version works muchhh better. I really like it :D

So now onto this beloved Access Violation.
I'm still getting this problem (naturally @_@). I can build all the samples without error.
I'll update with all the new info so as to clean the slate:

CEGUI v.5.0 SDK
MSVC++ 9.0 (2008) Express

the code:

Code: Select all

Window* ViewFullscreen = wmgr.createWindow("WindowsLook/MenuItem", "root/menubar/view/popup/fullscreen");
            ViewPopup->addChildWindow(ViewFullscreen);
            ViewFullscreen->setText("Toggle Fullscreen");
            ViewFullscreen->subscribeEvent(MenuItem::EventClicked, Event::Subscriber(&Interface::EventFunctions::ViewFullscreen, &this->EventHandler));


some barebones class definitions so you get the idea (I got rid of functions etc that aren't involved in any way, for ease of reading):

Code: Select all

class Interface
{
public:
   Interface();

   class EventFunctions
   {
   public:
      bool ViewFullscreen(const EventArgs& args);
   } EventHandler;

   void InitWidgets();
};


The line causing problems is in InitWidgets(), which is called during the Interface constructor.

Anyways, hopefully the new version and new compiler will help a little bit. xD In any event, this environment and new SDK are awesome anyways :]

User avatar
CrazyEddie
CEGUI Project Lead
Posts: 6760
Joined: Wed Jan 12, 2005 12:06
Location: England
Contact:

Postby CrazyEddie » Wed Feb 06, 2008 09:42

Hehe :) So, we're finally back where we started - at least this time you're using code that is somewhat similar to what we all have :lol:

I'm still having some trouble nailing down the cause of the issue. While on the one hand I want to ask you to confirm that 'this->EventHandler' is a valid pointer, I am also aware that this should make no difference at subscription time (if this were the case it should only bomb when the event is fired).

Do you get a more useful call stack in VC++ 9? Or is it the same as the other one you posted?

As an experiment, to try to narrow this down, can you create a free function and try subscribing with that - this would eliminate a lot of possible troubles.

I'd like to be of more help, but I'm not sure what else to suggest. This is very hard when it's someone else's code :lol:

Rackle
CEGUI Team (Retired)
Posts: 534
Joined: Mon Jan 16, 2006 11:59
Location: Montréal

Postby Rackle » Wed Feb 06, 2008 16:49

The following code generates a menubar with a File popup menu containing a new and an open menuitem. Try to compile this code. If it works then investigate the differences between this code and yours. Note that I'm changing some of the datafile paths; either remove that section of code or ensure it points to the proper locations.

One difference is the use of addChildWindow() and events are registered to a member function rather than what appears to be a different class, or is that simply a namespace? In that case there's a type in the call to subscribeEvent().

menu.h

Code: Select all

#include "CEGuiSample.h"
#include "CEGUI.h"
#include "CEGUIDefaultResourceProvider.h"


class DemoSample : public CEGuiSample
{
public:
    bool initialiseSample()
   {
      using namespace CEGUI;

      // The executable is stored within <cegui>/bin
      // The following will change the location of the datafiles from their default of
      // ../datafiles (which works well for samples) to <cegui>/samples/datafiles
      DefaultResourceProvider* rp = reinterpret_cast<DefaultResourceProvider*>(System::getSingleton().getResourceProvider());
      rp->setResourceGroupDirectory("fonts",         "C:/Programming/CEGUI/CEGUI_head/samples/datafiles/fonts/");
      rp->setResourceGroupDirectory("imagesets",      "C:/Programming/CEGUI/CEGUI_head/samples/datafiles/imagesets/");
      rp->setResourceGroupDirectory("layouts",      "c:/programming/_Projects/CeguiTestBed/");
      rp->setResourceGroupDirectory("looknfeels",      "C:/Programming/CEGUI/CEGUI_head/samples/datafiles/looknfeel/");
      rp->setResourceGroupDirectory("lua_scripts",   "C:/Programming/CEGUI/CEGUI_head/samples/datafiles/lua_scripts/");
      rp->setResourceGroupDirectory("schemes",      "C:/Programming/CEGUI/CEGUI_head/samples/datafiles/schemes/");

      Font::setDefaultResourceGroup("fonts");
      Imageset::setDefaultResourceGroup("imagesets");
      WindowManager::setDefaultResourceGroup("layouts");
      WidgetLookManager::setDefaultResourceGroup("looknfeels");
      ScriptModule::setDefaultResourceGroup("lua_scripts");
      Scheme::setDefaultResourceGroup("schemes");

      try
      {
         WindowManager& wmgr = WindowManager::getSingleton(); // Init pointer to Window Manager
         Window* Root = wmgr.createWindow("DefaultWindow", "root"); // Create root window
         System::getSingleton().setGUISheet(Root); // Set root window
         String CeguiLook;
         CeguiLook = "WindowsLook";
         //CeguiLook = "TaharezLook";
         SchemeManager::getSingleton().loadScheme(CeguiLook + ".scheme");
         System::getSingleton().setDefaultMouseCursor(CeguiLook, "MouseArrow");

         Font* font;
         if(FontManager::getSingleton().isFontPresent("Commonwealth-10"))
            font = FontManager::getSingleton().getFont("Commonwealth-10");
         else
            font = FontManager::getSingleton().createFont("Commonwealth-10.font");

         // create menu bar window
         Menubar* menuBar = static_cast<Menubar*>(wmgr.createWindow(CeguiLook + "/Menubar", "root/menubar"));
         UDim bar_bottom(0, font->getLineSpacing(2));
         menuBar->setArea(UDim(0,0),UDim(0,0),UDim(1,0),bar_bottom);
         menuBar->setSize(UVector2(UDim(1.0f, 0.0f), UDim(0.05f, 0.0f)));
         menuBar->setAlwaysOnTop(true);
         Root->addChildWindow(menuBar);

         // create file menu item window
         MenuItem* menuFile = static_cast<MenuItem*>(wmgr.createWindow(CeguiLook + "/MenuItem", "root/menubar/file"));
         menuFile->setText("File");
         menuBar->addChildWindow(menuFile);

         // create file menu popup window
         PopupMenu* popupMenuFile = static_cast<PopupMenu*>(wmgr.createWindow(CeguiLook + "/PopupMenu", "root/menubar/file/popup"));
         menuFile->addChildWindow(popupMenuFile);

         // create the "new" menuitem
         MenuItem* menuFileNew = static_cast<MenuItem*>(wmgr.createWindow(CeguiLook + "/MenuItem", "root/menubar/file/popup/new"));
         menuFileNew->setText("New");
         popupMenuFile->addChildWindow(menuFileNew);
         menuFileNew->subscribeEvent(MenuItem::EventClicked, Event::Subscriber(&DemoSample::Event_FileNew, this));

         // create the "open" menuitem
         MenuItem* menuFileOpen = static_cast<MenuItem*>(wmgr.createWindow(CeguiLook + "/MenuItem", "root/menubar/file/popup/open"));
         menuFileOpen->setText("Open");
         popupMenuFile->addChildWindow(menuFileOpen);
         menuFileOpen->subscribeEvent(MenuItem::EventClicked, Event::Subscriber(&DemoSample::Event_FileOpen, this));

         mStatusText = wmgr.createWindow(CeguiLook + "/StaticText", "root/status");
         mStatusText->setPosition(UVector2(UDim(0.2f, 0.0f), UDim(0.8f, 0.0f)));
         mStatusText->setSize(UVector2(UDim(0.1f, 0.0f), UDim(0.05f, 0.0f)));
         Root->addChildWindow(mStatusText);
      }
      catch(Exception &e)
      {
         #if defined( __WIN32__ ) || defined( _WIN32 )
            MessageBox(NULL, e.getMessage().c_str(), "Error initializing the demo", MB_OK | MB_ICONERROR | MB_TASKMODAL);
         #else
            std::cerr << "Error initializing the demo:" << e.getMessage().c_str() << "\n";
         #endif
      }

      return true;
   }

    void cleanupSample(void)
   {
   }

   bool Event_FileNew(const CEGUI::EventArgs& args)
   {
      mStatusText->setText("New");
      return true;
   }

   bool Event_FileOpen(const CEGUI::EventArgs& args)
   {
      mStatusText->setText("Open");
      return true;
   }

private:
   CEGUI::Window* mStatusText;
};



main.cpp

Code: Select all

#if defined( __WIN32__ ) || defined( _WIN32 )
   #define WIN32_LEAN_AND_MEAN
   #define NOMINMAX
   #include "windows.h"
#endif

#include "menu.h"

#if defined( __WIN32__ ) || defined( _WIN32 )
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,int nCmdShow)
#else
int main(int argc, char *argv[])
#endif
{
    DemoSample app;
    int i = app.run();
    return i;
}

Browser12
Not too shy to talk
Not too shy to talk
Posts: 42
Joined: Thu Jan 24, 2008 06:30
Location: UW-Madison
Contact:

Postby Browser12 » Thu Feb 07, 2008 04:07

Hey!

Eddie: Mk, I tried it. I get the same result when I do something like this:

Code: Select all

ViewFullscreen->subscribeEvent(MenuItem::EventClicked, Event::Subscriber(&GlobalFunction));

with a global function like:

Code: Select all

bool GlobalFunction(const EventArgs& args)
{
   return true;
}

The callstack I get both ways is this:

Code: Select all

   World Writer.exe!Interface::InitWidgets()  Line 84 + 0x5b bytes
    World Writer.exe!Interface::Interface()  Line 21
    World Writer.exe!ManagerTemplate<Interface>::Start()  Line 18 + 0x2b bytes
    World Writer.exe!AppLoop::AppLoop()  Line 29
    World Writer.exe!wmain(int argc=1, wchar_t * * argv=0x00356868)  Line 32 + 0x8 bytes
    World Writer.exe!__tmainCRTStartup()  Line 579 + 0x19 bytes
    World Writer.exe!wmainCRTStartup()  Line 399


Rackle: I set the application up and it builds fine. The only problem I'm having is that it crashes on this line:

Code: Select all

DefaultResourceProvider* rp = reinterpret_cast<DefaultResourceProvider*>(System::getSingleton().getResourceProvider());

Code: Select all

Assertion failed: ms_Singleton, file C:\dev\cegui\cegui_mk2\include\ceguisingleton.h, line 79

I looked at that line in CEGUISingleton.h and it looked from that line like my cegui::system wasn't initialized properly.
I didn't know why it was, so I just manually intialized a new cegui::system with an opengl renderer.

Get this: RACKLE'S RUNS. :O
So that means something good, right? *runs off to compare his code with Rackle's.* [edit] I thought for sure it was because I was adding Windows and you were adding MenuItems to the PopupMenu, Rackle, but it didn't work. >< I was so excited. Still at it...

Anyways, I thought I'd post something that I had thought way back when was possibly the problem-causer.
I use this template for my Interface class (the one whose 'this' i pass to the event subscriber). It's something snazzy my friend taught me (who's actually good at C++ xD). So when I pass 'this' to the subscriber, this is where that 'this' is pointing. You'll see the reference to ManagerTemplate in the callstack, so this is where that's coming from.

Code: Select all

template <class Derived> class ManagerTemplate
{
   public:
      ~ManagerTemplate() {}

//////////////////////////////////////////////////////////////////////
// Methods
//////////////////////////////////////////////////////////////////////

      static void Start(void)
      {
         if (Instance != NULL) return;
         Instance = new Derived;
      }

      static void Stop(void)
      {
         if (Instance != NULL) delete Instance;
         Instance = NULL;
      }

      static Derived &Get(void)
      {
         assert(Instance != NULL);
         return *Instance;
      }
   protected:
      ManagerTemplate() {}
   private:
      static Derived *Instance;
};

template <class Derived> Derived *ManagerTemplate<Derived>::Instance = NULL;

I made another application before, as I posted a few posts ago, to see if I still got the access violation. I did, but no template was involved. So I figure this is unrelated. I think static Derived *Instance means the pointer is static, but the instance isn't, so i don't think the 'this' I pass to the subscriber is a constant, or anything like that. Also, I think a constant instance of the Interface object would have given me a lot more problems than passing to the event subscriber. But I thought I should just post it anyways, for a better understanding of the program. :3

In any event, I reeeally appreciate that you both are taking the time to continue to help me with this... you have no idea how grateful i am :X


Return to “Help”

Who is online

Users browsing this forum: No registered users and 23 guests