Linker bzw. internal Compiler error



  • Student83 schrieb:

    Also ich weis nicht was an dem Funktionsaufruf hässlich sein soll. Dann schau dir mal die Implementierung von boost::function an. Das ist meiner Meinung nach hässlich. Mir geht es eigentlich nur darum eine Wrapper-Klasse um void* zu bauen.

    Weder ist boost::function schlecht, noch hat es einen entferntesten Sinn einen Wrapper um void* zu machen.

    reinterpret_cast<void(*)()>(myPtr.GetPtr())();
    

    Was daran hässlich sein soll? Das ist doch jetzt ein Witz?



  • Also habe ich das jetzt richtig verstanden, dass der Compiler von Visual Studio 2010 wohl den Funktionszeiger nicht im void*-Zeiger speichern kann? Ich habe jetzt aber gelesen, dass mit dem C++11 Standard der reinterpret_cast garantiert wieder die gleiche Adresse zurückzuliefern. Habe desshalb mal Visual Studio 11 installiert und tatsächlich es funktioniert jetzt.

    @cooky451
    Das Problem mit dem Code von dir ist, dass du anstatt eines void-Pointers einen Funktionszeiger genommen hast. Mit diesem müsste ich mich aber auf eine Funktionsdefinition beschränken. Ich möchte aber, dass man die Parameter der Funktionen beliebig wählen kann. Das geht halt nur über einen void-Pointer.



  • Student83 schrieb:

    Also habe ich das jetzt richtig verstanden, dass der Compiler von Visual Studio 2010 wohl den Funktionszeiger nicht im void*-Zeiger speichern kann? Ich habe jetzt aber gelesen, dass mit dem C++11 Standard der reinterpret_cast garantiert wieder die gleiche Adresse zurückzuliefern. Habe desshalb mal Visual Studio 11 installiert und tatsächlich es funktioniert jetzt.

    @cooky451
    Das Problem mit dem Code von dir ist, dass du anstatt eines void-Pointers einen Funktionszeiger genommen hast. Mit diesem müsste ich mich aber auf eine Funktionsdefinition beschränken. Ich möchte aber, dass man die Parameter der Funktionen beliebig wählen kann. Das geht halt nur über einen void-Pointer.

    Schon mal was von Templates gehört? Ganz tolle Sache, menJung.
    Außerdem, welcher Code?



  • Der Code bei ideone: http://ideone.com/XYDP5
    Irgendwie habe ich gewusst, dass jetzt jemand mit Templates kommt. Templates sind mal davon abgesehen, dass sie das Debugging erschweren bis unmöglich machen, oft schlechter zu lesen sind und die Trennung von definition und implementation (sagt man das so?) verhindern ganz nett. In diesem Fall für mich leider völlig unanwendbar, da alles dynamisch zu Laufzeit erzeugt wird und templates hier die Funktionalität nur einschränken würden.
    Nur um mal ein Beispiel zu nennen: Ich nehme jetzt eine Template Klasse um die Funktionszeiger auch mit unterschiedlichen Paramtern speichern zu können (wobei das auch nur eingeschränkt funktioniert). Nun brauche ich aber auch eine Liste in der ich diese Template-Objekte speichern kann, da der Endanwender das Framework auch um eigene Funktionalität erweitern können soll. Also brauche ich eine Liste die mehr oder weniger Objekte beliebigen Typs aufnimmt. Dann kann ich aber auch gleich die Funktionszeiger als void* ablegen und habe mir dieses Templatekrebsgeschwür erspart.



  • Student83 schrieb:

    Der Code bei ideone: http://ideone.com/XYDP5
    Irgendwie habe ich gewusst, dass jetzt jemand mit Templates kommt. Templates sind mal davon abgesehen, dass sie das Debugging erschweren bis unmöglich machen, oft schlechter zu lesen sind und die Trennung von definition und implementation (sagt man das so?) verhindern ganz nett. In diesem Fall für mich leider völlig unanwendbar, da alles dynamisch zu Laufzeit erzeugt wird und templates hier die Funktionalität nur einschränken würden.
    Nur um mal ein Beispiel zu nennen: Ich nehme jetzt eine Template Klasse um die Funktionszeiger auch mit unterschiedlichen Paramtern speichern zu können (wobei das auch nur eingeschränkt funktioniert). Nun brauche ich aber auch eine Liste in der ich diese Template-Objekte speichern kann, da der Endanwender das Framework auch um eigene Funktionalität erweitern können soll. Also brauche ich eine Liste die mehr oder weniger Objekte beliebigen Typs aufnimmt. Dann kann ich aber auch gleich die Funktionszeiger als void* ablegen und habe mir dieses Templatekrebsgeschwür erspart.

    Hä? Du willst eine Liste mit Funktionszeigern die alle auf verschiedene Funktions-typen zeigen?

    Schlechtes Design, nichts weiter.



  • Man kann wenn es denn sein muss sowas verwenden (wenn ich dein Vorhaben verstanden hab):

    #include <boost/any.hpp>
    #include <string>
    
    struct func
    {
          void operator()(int, std::string const&) {}
    };
    
    int main()
    {
          std::vector<boost::any> vec;
          vec.push_back(func());
    
          boost::any_cast<func>(vec[0])(5, "d");
    }
    


  • Hacker schrieb:

    Hä? Du willst eine Liste mit Funktionszeigern die alle auf verschiedene Funktions-typen zeigen?

    Schlechtes Design, nichts weiter.

    Im Prinzip ist das so. Klar in einem "abgeschlossenen" Programm, dass nicht erweitert werden können muss könnte ich jeweils für jeden Funktionstyp eine eigene Liste führen. Aber das Programm bzw. die Library muss eben auch nach dem Kompilieren noch für andere Funktionstypen erweiterbar sein. Das hat nichts mit schlechtem Design zu tun. Und selbst wenn doch. Was nützt mir ein super Design wenn die Library am Ende niemand oder nur eingeschränkt verwendet werden kann.

    Hacker schrieb:

    Man kann wenn es denn sein muss sowas verwenden (wenn ich dein Vorhaben verstanden hab):

    #include <boost/any.hpp>
    #include <string>
    
    struct func
    {
          void operator()(int, std::string const&) {}
    };
    
    int main()
    {
          std::vector<boost::any> vec;
          vec.push_back(func());
    
          boost::any_cast<func>(vec[0])(5, "d");
    }
    

    Im Prinzip trifft es das. Nur will ich wirklich kein boost::any und Konsorten verwenden (das ist in meinen Augen wirklich schlechtes Design), sondern stattdessen vereinfacht gesagt meine Ptr-Klasse die einen Wrapper um einen void-Pointer darstellt nehmen.
    Alles was ich eigentlich noch wissen will ist, ob das mit C++11 jetzt garantiert ist, dass man einen Funktionszeiger (einer statischen Funktion) in einen void-Zeiger hinein und wieder zurück casten kann ohne, dass sich die Adresse verändert? Und ob das auch für unterschiedliche Plattformen gilt?



  • Und wie merkst du dir die Signatur der Funktion, damit spätere Aufrufe auch glatt laufen?



  • Die Ptr-Klasse ist ja nur die Basis auf der alles andere aufbaut. Jeder Handler hat eine virtuelle Invoke-Memberfunktion die das Aufrufen übernimmt.



  • Student83 schrieb:

    Die Ptr-Klasse ist ja nur die Basis auf der alles andere aufbaut. Jeder Handler hat eine virtuelle Invoke-Memberfunktion die das Aufrufen übernimmt.

    Das heißt, jeder handler hat seine eigene Funktion, oder? Denn "virtual" könnte sie nur sein, wenn sie die selbe Signatur wie die der Basisklasse hat - und somit ist der Vorteil einer gemeinsamen Basis wieder dahin.
    Oder wo kommen die Argumente her? Speichert der spezialisierte Handler die irgendwo?



  • fiedelity schrieb:

    Student83 schrieb:

    Die Ptr-Klasse ist ja nur die Basis auf der alles andere aufbaut. Jeder Handler hat eine virtuelle Invoke-Memberfunktion die das Aufrufen übernimmt.

    Das heißt, jeder handler hat seine eigene Funktion, oder? Denn "virtual" könnte sie nur sein, wenn sie die selbe Signatur wie die der Basisklasse hat - und somit ist der Vorteil einer gemeinsamen Basis wieder dahin.
    Oder wo kommen die Argumente her? Speichert der spezialisierte Handler die irgendwo?

    Im Moment ist das so, aber ich habe ja erst angefangen das event-system zu entwickeln. Bin mir da bei ein paar Punkten noch unsicher. Zum Beispiel bei dem von dir genannten wie ich das mit dem Funktionsaufruf am besten löse. Wie würdest du das denn machen? Du scheinst dich ja mit dem Thema ein wenig auszukennen.
    Mir geht es jetzt auch erstmal darum abzuchecken, ob das ganze vom Prinzip her überhaupt so funktioniert wie ich mir das vorgestellt habe. Was meinst du mit Argumenten? Die Funktionsparamter oder die Eventargumente?


Anmelden zum Antworten