[gelöst] pointer aus int zu klasse casten



  • Hallo,
    ich hoffe der Titel sagt schon das aus, was ich machen will 🙂

    ich habe einen Pointer auf eine Klasse als int vorliegen...dieser wurde so erzeugt:

    LuaPageControl PageControl(L,GTK_WIDGET(iParent));
    int(&PageControl);
    

    die Klasse LuaPageControl wurde so deklariert:

    class LuaPageControl:public LuaControl,public CPageControl
    {
      private:
        //GtkWidget *PageControl;
      protected:
    
      public:
        LuaPageControl(lua_State *l,GtkWidget *parent): LuaControl(l), CPageControl(parent)
        {}
        ~LuaPageControl() {};
    };
    

    ich möchte nun in einer anderen (statischen) Funktion diesen pointer wieder dereferenzieren...

    static int do_PageControlAddPage(lua_State *L)
    {
     int iPageControl=luaL_checkinteger(L,1);
     const char *caption=luaL_checkstring(L,2);
    
     g_print("Adding Page To Pagecontrol (0x%x) with label '%s'...\n",iPageControl,caption);
    
     LuaPageControl PageControl=(LuaPageControl)iPageControl;
    
     GtkWidget *vbox=PageControl.AddPage(caption,-1);
    
     lua_pushinteger(L,int(vbox));//put handle of content to stack
     return 1;//return 1 value (handle)
    }
    

    wie zu erkennen ist, ist iPageControl der Pointer als int.
    als Fehlermeldung bekomme ich:

    lgui.cxx: In function ‘int do_PageControlAddPage(lua_State*)’:
    lgui.cxx:92: error: no matching function for call to ‘LuaPageControl::LuaPageControl(int&)’
    lgui.cxx:58: note: candidates are: LuaPageControl::LuaPageControl(lua_State*, GtkWidget*)
    lgui.cxx:52: note: LuaPageControl::LuaPageControl(const LuaPageControl&)

    ich habe auch schon versucht den Pointer mittels &PageControl=iPageControl zu setzen, was leider auch nicht geklappt hat 🙂

    weis jemand, wie ich diesen Cast durchführen kann?

    Gruß Frank


  • Mod

    Da ist ein reinterpret_cast angesagt.

    Aber: Warum? Das macht alles gar keinen Sinn. Außer vielleicht als sehr gutes Negativbeispiel.

    Außerdem: Viel Spaß auf 64 Bit Systemen...



  • Da du in dem int die Adresse transportierst, müsste es doch so lauten:

    LuaPageControl* PageControl=(LuaPageControl*)iPageControl;
    

    bzw. besseres C++ ohne C-style cast

    LuaPageControl* PageControl=reinterpret_cast<LuaPageControl*>(iPageControl);
    

    Aber so etwas mit einem int zu machen ist schon merkwürdig. Wenn es wenigstens ein void* wäre.

    Lars



  • erstmal danke. es compiliert nun...

    lua kennt kein void* nur Typen wie "int" "const char*" und "bool"

    habe leider keine Möglichkeit gefunden, den zugriff auf die klasse anders zu realisieren.

    ich müsste doch jetzt eigentlich mittels

    PageControl->AddPage(caption,-1);
    

    auf das Feld zugreifen können, oder? das macht er auch, nur dass ich scheinbar nicht auf private felder der klasse (innerhalb der addpage-Methode) zugreifen kann.

    GtkWidget *CPageControl::AddPage(const char *caption,int position)
    {
      g_print("Adding Page (CPageControl)\n");
    	GtkWidget *label=gtk_accel_label_new(caption);
      GtkWidget *vbox=gtk_vbox_new(2,false);
    	gtk_widget_show(vbox);
    	g_print("now inserting (%x)\n",int(PageControl));
    
    	gtk_notebook_insert_page(GTK_NOTEBOOK(PageControl),vbox,label,position);
    	g_print("inserted\n");
      return vbox;
    }
    

    die gtk_notebook-zeile bringt das programm zum abstürzen, Pagecontrol ist auf irgendetwas gesetzt, aber nicht das feld der klasse.
    rufe ich die methode direkt nach dem constructor auf, funktioniert es.

    Gruß Frank



  • frank schrieb:

    lua kennt kein void* nur Typen wie "int" "const char*" und "bool"

    Eigentlich kennt Lua keins davon. nil, boolean, number, string, function, userdata, thread und table sind die Datentypen in Lua. userdata wäre das richtige für Pointer.

    lua_pushlightuserdata(L, vbox);
    


  • userdata bringt mir aktuell mehr probleme:

    lua_pushlightuserdata(L,PageControl);
    

    error: cannot convert ‘LuaPageControl’ to ‘void*’



  • Du musst dich schon entscheiden, ob du ein Objekt oder einen Zeiger auf ein Objekt pushen willst.



  • Nukularfüsiker schrieb:

    Du musst dich schon entscheiden, ob du ein Objekt oder einen Zeiger auf ein Objekt pushen willst.

    mhm...klar mit & die Adresse holen 😉

    das problem ist, dass ich dann nicht die adresse direkt verwenden kann sondern diese erstmal dereferenzieren muss...und mein "objekt" selbst ist eigentlich schon ein Pointer:

    GtkWidget *PageControl;
    bzw.
    GtkWidget *vbox=gtk_vbox_new(2,false);
    

    mit & hätte ich dann also den pointer auf nen pointer 😞
    vorher hab ich ja den objektzeiger selbst auf int gecastet..nur wie gehts das mit void*? einfach mit * gehts nicht (error: ‘void*’ is not a pointer-to-object type)

    trotzdem besteht das ursprungsproblem immer noch...der code sieht jetzt so aus:

    static int do_CreatePageControl(lua_State *L)
    {
      gpointer iParent=lua_touserdata(L,1);
    
      g_print("Adding Pagecontrol to Parent 0x%x...\n",iParent);
    
      LuaPageControl PageControl(L,GTK_WIDGET(iParent));
    
      PageControl.AddPage("Test",-1);
    
      GtkWidget *button=gtk_button_new_with_label("Test");
      gtk_widget_show(button);
      gtk_box_pack_start(GTK_BOX(iParent),button, TRUE, TRUE, 0);
    
      button=gtk_button_new_with_label("Test2");
      gtk_widget_show(button);
      gtk_box_pack_start(GTK_BOX(iParent),button, TRUE, TRUE, 0);
    
      lua_pushlightuserdata(L,&PageControl);//put pointer of Pagecontrol to stack
      //lua_pushinteger(L,int(&PageControl));//put pointer of Pagecontrol to stack
      return 1;//return 1 value (handle)
    }
    
    static int do_PageControlAddPage(lua_State *L)
    {
      gpointer iPageControl=lua_touserdata(L,1);
      const char *caption=luaL_checkstring(L,2);
    
      g_print("Adding Page To Pagecontrol (0x%x) with label '%s'...\n",iPageControl,caption);
    
      LuaPageControl* PageControl=reinterpret_cast<LuaPageControl*>(iPageControl);
    
      GtkWidget *vbox=PageControl->AddPage(caption,-1);
    
      //lua_pushinteger(L,int(vbox));//put handle of content to stack
      lua_pushlightuserdata(L,&vbox);//put pointer of vbox on stack
      return 1;//return 1 value (handle)
    }
    

    Gruß Frank



  • frank schrieb:

    vorher hab ich ja den objektzeiger selbst auf int gecastet..nur wie gehts das mit void*?

    Da ist kein Cast notwendig.

    trotzdem besteht das ursprungsproblem immer noch...

    Vermutlich ist dein Problem, dass PageControl wird beim verlassen der Funktion zerstört wird. Du musst das Ding mit new anlegen, damit es länger lebt. Und wenn du es nicht mehr brauchst, mit delete wieder löschen. Kleines Einmaleins... vielleicht mal ein C++-Grundlagenbuch lesen?



  • Nukularfüsiker schrieb:

    frank schrieb:

    vorher hab ich ja den objektzeiger selbst auf int gecastet..nur wie gehts das mit void*?

    Da ist kein Cast notwendig.

    das object direkt übergeben an lua_pushlightuserdata ist ja nicht möglich...

    wie gesagt, vorher hab ich den Objectzeiger direkt nach int gecastet "int(Pagecontrol)"

    mhm, das mit der automatischen freigabe könnte das problem sein...muss ich mal schauen, ob ich das irgendwie lösen kann...
    btw. das Grundlagenbuch (Einstieg in C++) liegt neben mir...und ich schau auch rein 🙂

    Gruß Frank



  • frank schrieb:

    wie gesagt, vorher hab ich den Objectzeiger direkt nach int gecastet "int(Pagecontrol)"

    Das funktioniert nicht. Der Compiler mag das zulassen, aber es kommt kein sinnvolles Ergebnis dabei raus.

    Die Lösung ist simpel:

    LuaPageControl *pageControl = new LuaPageControl(L,GTK_WIDGET(iParent));
    lua_pushlightuserdata(L, pageControl);
    

    Das sollte funktionieren. Du musst dir aber überlegen, wo du das dazugehörige delete unterbringst.



  • ok, ich schau mal, wo ich das delete unterbringen kann...muss das wahrscheinlich über die GUI machen (gui-element freigeben und über angehängen Pointer auf klasse diese auch freigeben), da LUA keine Unload-methode aufruft

    die anderen Sachen konnte ich lösen...es sieht jetzt so aus:

    //hauptprogramm:
    void *SciTEGTK::GetSidebarHandle()
    
    {
      g_print("Sidebar-Handle (Scite): 0x%x\n",int(SidebarContainer));
    
      return SidebarContainer;
    
    }
    
    //modul:
    static int do_CreatePageControl(lua_State *L)
    {
      gpointer iParent=lua_touserdata(L,1);
    
      LuaPageControl *PageControl=new LuaPageControl(L,GTK_WIDGET(iParent));
    
      lua_pushlightuserdata(L,PageControl);//put pointer of Pagecontrol to stack
      return 1;//return 1 value (handle)
    }
    //...
    static int do_PageControlAddPage(lua_State *L)
    {
      gpointer iPageControl=lua_touserdata(L,1);
      const char *caption=luaL_checkstring(L,2);
    
      LuaPageControl* PageControl=reinterpret_cast<LuaPageControl*>(iPageControl);
    
      GtkWidget *vbox=PageControl->AddPage(caption,-1);
    
      lua_pushlightuserdata(L,&vbox);//put pointer of vbox on stack
      return 1;//return 1 value (handle)
    }
    

    der komplette/aktuellste code ist auf http://scite-gui.googlecode.com

    Danke an alle, die mir geholfen haben

    Gruß Frank


Anmelden zum Antworten