Variablenmanager ausgang undefiniert ?!



  • Hallo nochmal, ich beschäftige mich seit heute wieder damit den Variablenmanager von einem anderen Thread von mir einzubauen.
    Ich habe parallel zum tatsächlichen Projekt immer kleine projekte in VC2010, wo ich das ganze teste.
    Nunja ich habe es getestet und bekomme trotzdem irgendwas anderes in dem hauptprojekt raus 😉

    #ifndef ICONSOLE_H_
    #define ICONSOLE_H_
    
    #pragma once
    
    #include <windows.h>
    #include <iostream>
    #include <string>
    #include <sstream>
    #include <map>
    #include "IComponent.h"
    
    #include "GlobalDefine.h"
    
    #include <boost/lexical_cast.hpp>
    #include <boost/shared_ptr.hpp>
    
    #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' "\
    "version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
    
    LRESULT CALLBACK IConsole_WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
    
    //-------------------------------------------------------------------------------//
    
    class IVariable {
      public:
    	  virtual void printTo(std::string& out) const = 0;
    };
    
    template <typename T>
    class VariableImpl : public IVariable {
      public:
        explicit VariableImpl(T* managed = NULL) : m_managed(managed) {}
        void setManaged(T* managed) { m_managed = managed; }
        virtual void printTo(std::string& out) const {
    	  std::stringstream ss;
    	  ss << *m_managed;
          out = ss.str();
        }
      private:
        T* m_managed;
    };
    
    template <typename T>
    boost::shared_ptr<IVariable> make_variable(T const& var) {
      return boost::shared_ptr<IVariable>(new VariableImpl<T const> (&var));
    }
    
    //--------------------------------------------------------------------------------------//
    
    class IConsole : public IComponent
    {
    public:
    
    	IConsole(void);
    	~IConsole(void);
    
    	void Update();
    	IResult Initialize();
    	IResult Terminate();
    
    	void Test() { MessageBoxA(0,"Hallo",0,0); }
    
    	//--------------------------------------------------------//
    
    	 template <typename T>
         void AddItem(std::string name, T const& v) { m_variables[name] = make_variable(v); _listItems++; }
    
    	 //--------------------------------------------------------//
    
    private:
    
    	//-------------Windows---------//
    	HWND _consoleWindow;
    	HWND _listWindow; 
    	MSG msg;
    	int _listItems;
    
    	void UpdateList(std::string content);
    	void DeleteList(int items);
    	//-----------------------------//
    
    	//-----------------------------//
    	std::map<std::string, boost::shared_ptr<IVariable> > m_variables;
    	//-----------------------------//
    
    	void Create() { MessageBoxA(0,"Created",0,0);}
    
    };
    
    #endif
    
    #include "IConsole.h"
    
    IConsole::IConsole()
    {
    
    }
    
    IConsole::~IConsole()
    {
    
    }
    
    IResult IConsole::Initialize()
    {
    
    	HINSTANCE hinst = GetModuleHandle(NULL);
    
    	WNDCLASS wndclass;
    
        wndclass.style = CS_HREDRAW | CS_VREDRAW;
        wndclass.lpfnWndProc = IConsole_WndProc;
        wndclass.cbClsExtra = 0;
        wndclass.cbWndExtra = 0;
        wndclass.hInstance = hinst;
        wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
        wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
        wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
        wndclass.lpszMenuName = NULL;
        wndclass.lpszClassName = TEXT("Console");
    
        if (!RegisterClass(&wndclass)) {
            return IRESULT_ERROR;
        }
    
    	//------------------------Erstelle Fenster-------------------//
    
        _consoleWindow = CreateWindow(TEXT("Console"),
                                      TEXT("Console"),
                                      WS_OVERLAPPEDWINDOW, 
    								  CW_USEDEFAULT,
    								  CW_USEDEFAULT,
    								  500,
    								  400,
    								  NULL,
    								  NULL,
    								  hinst,
    								  NULL);
    
    	if(!_consoleWindow)
    		return IRESULT_ERROR;
    
        ShowWindow(_consoleWindow,SW_SHOWNORMAL);
        UpdateWindow(_consoleWindow);
    
    	//------------------------Erstelle Listbox---------------------//
    	// Die Größe der Listbox wird an die größe des Konsolenfensters angepasst
    	// , da sich dieses nicht in der Größe verändert und eine dynamische
    	// Umformung nicht notwendig ist
    	//
    
    	 IConsole::_listWindow = CreateWindow(TEXT("LISTBOX"), 
    		                        TEXT("Console"), 
    								WS_CHILD | WS_VISIBLE| WS_BORDER | LBS_DISABLENOSCROLL | WS_VSCROLL   , 
    								0, 
    								0, 
    								484, 
    								365,
    								_consoleWindow, 
    								NULL, 
    								hinst, 
    								NULL);
    
    	 _listItems = 0;
    
    	return IRESULT_OK;
    }
    
    IResult IConsole::Terminate()
    {
    	return IRESULT_OK;
    
    }
    
    void IConsole::Update()
    {
    	DeleteList(_listItems);
    
        for(std::map<std::string, boost::shared_ptr<IVariable> >::const_iterator it = this->m_variables.begin(); it != this->m_variables.end(); ++it) {
    		std::stringstream ss;
    		std::string st;
    		it->second->printTo(st);
    		MessageBoxA(0,st.c_str(),0,0);
    		ss << (it->first) << " = " << st << std::endl;
    		UpdateList(ss.str());
        }
    
    	if(GetMessage(&msg, NULL, 0, 0))
    	{
    			TranslateMessage(&msg);
    			DispatchMessage(&msg);
    	}
    }
    
    void IConsole::UpdateList(std::string content)
    {
    	SendMessage(_listWindow, LB_ADDSTRING,0,(LPARAM)content.c_str());
    }
    
    void IConsole::DeleteList(int items)
    {
    	for(int i = items; i > 0; i--)
    	{
    		SendMessage(_listWindow,LB_DELETESTRING,(WPARAM)i,NULL);
    	}
    }
    
    LRESULT CALLBACK IConsole_WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    	switch (msg)
    	{
    	case WM_CREATE:
    
    	case WM_DESTROY:
    		PostQuitMessage(0);
    		break;
    	default:
    		return DefWindowProc(hwnd, msg, wParam, lParam);
    	}
    	return 0;
    
    }
    

    Wäre euch sehr sehr dankbar, wenn jemand den Fehler finden, denn ich seh da keinen.
    Danke im Voraus



  • Hallo,

    irgendwas anderes herauszubekommen ist irgendwie eine seltsame Fehlerbeschreibung.

    was mir auffällt ist allerdings folgendes:

    LRESULT CALLBACK IConsole_WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
        switch (msg)
        {
        case WM_CREATE:
            // mindestens break fehlt
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc(hwnd, msg, wParam, lParam);
        }
        return 0;
    
    }
    

    vlt. ist das irgendwas anderes.

    Gruß



  • Danke für den Hinweis aber das war es nicht.Ich kann jetzt nur noch folgendes sagen:

    Wenn ich den Manager in meiner Initialize Funktion ( einer anderen klasse ) erstelle, dort eine Variable hinzufüge und direkt ausgeben, ist alles richt.

    Wenn ich jedoch doe ausgabefunction in einer anderen funktion als Initialize ( z.B in Update ) ausführe bekomme ich nur schrott raus.
    Kann sein, dass es was mit den smartpointern zu tun hat, die dann auf einen null-pointer zeigen.....



  • Was mir auffaellt: dein Variablen Manager speichert nur Zeiger auf und keine Kopien von den Variablen die du in ihn reinschreibst.

    Das kann natuerlich zu Problemen fuehren.

    PS:
    reduziere bitte den Code auf das wesentliche - aktuell ist sehr viel Boilerplate Code fuer Fenstererstellung etc. vorhanden - der ja nicht zum Problem beitraegt.



  • Und was soll ich da machen ?? Wie kann man eine kopie von einem template erstellen ?

    Hier ist das mal zusammengefasst:

    class Variable {
      public:
        virtual void printTo(std::string& out) const = 0;
    };
    
    template <typename T>
    class VariableImpl : public Variable {
      public:
        explicit VariableImpl(T* managed = NULL) : m_managed(managed) {}
        void setManaged(T* managed) { m_managed = managed; }
        virtual void printTo(std::string& out) const {
    	  std::stringstream ss;
    	  ss << *m_managed;
          out = ss.str();
        }
      private:
        T* m_managed;
    };
    
    template <typename T>
    Variable* make_variable(T const& var) {
      Variable* temp = new VariableImpl<T const>(&var);
      return temp;
    }
    
    class VariableManager {
      public:
         template <typename T>
         void addVariable(std::string name, T const& v) { m_variables[name] = make_variable(v); }
         std::string Out() {
    		 std::string out;
            for(std::map<std::string,Variable* >::const_iterator it = this->m_variables.begin(); it != this->m_variables.end(); ++it) {
    			std::stringstream ss;
    			std::string st;
    			it->second->printTo(st);
    			ss << (it->first) << " = " << st << std::endl;
    		    out = ss.str();
    			MessageBoxA(0,st.c_str(),0,0);
           }
           return out;
         }
      private:
        std::map<std::string,Variable*> m_variables;
    };
    


  • Bob Wolfskin schrieb:

    Und was soll ich da machen ?? Wie kann man eine kopie von einem template erstellen ?

    statt
    Variable* temp = new VariableImpl<T const>(&var);
    einfach
    Variable* temp = new VariableImpl<T>(var);
    schreiben?

    Ich verstehen deine Frage leider nicht.



  • Hallo,

    ich nehme an es wird in dem beschrieben Fall zu einer Ausnahme kommen, weil der Zeiger in der Variable auf einen ungültigen Bereich zeigt da die auszugebende Variable nicht mehr existiert.

    Testen kannst du das z.B. mit folgendem Code:

    // funktion im VaribleManager zum testen ergänzen. 
    template<typename T>
    void GetValue( const std::string& Name, T& RefToValue)
    {
    	try
    	{
    		RefToValue = ( (VariableImpl<T>*)(m_variables[Name]).get() )->GetValue();
    	}
    	catch (...)
    	{
    		std::string Text = "Objekt " + Name + " ist nicht mehr vorhanden.";
    		MessageBoxA( 0, Text.c_str(), 0, 0 );
    	}
    }
    

    Die Funktion GetValue() aufrufen um den Wert des Objektes zu erhalten.
    Das ist sicherlich nicht die optimale Variante, aber ein gangbarer Weg um deinen Problemfall zum testen

    zukünftig:
    Versuche das Objekt (Variable) mit einem shared_ptr und new zu erstellen. Der Smart-Pointer kümmert sich dann um die Freigabe.
    Wenn das die Lösung ist solltest du dich nochmal über die Lebenszeiten von Objekten informieren sowie über Pointer & SmartPointer.

    Ist das nicht der Fehler dann gib bitte eine genauere Beschreibung

    Gruß



  • Hmm ich sehe jetzt glaub ich warum das die ganze Zeit so eine Scheiße macht.
    Ich erstelle in einer Methode eine lokale Variable und lasse auf diese zeigen.In einer anderen Funktion ruf ich sie wieder auf, natürlich gibt es sie dort nicht.......

    Danke Leute


Log in to reply