delegate und function pointer



  • Hallo

    Ich bin dabei für alten C++ code einen wrapper zu schreiben. Nun bin ich an einem punkt wo ich dem alten code functionspointer übergeben muss.
    Ich möchte die Funktionspointer gerne auf der managed seite initialisieren. das heisst ich habe mir delegates gemacht, die im endeffekt gleich aussehen wie die void* aus dem alten code (glaube ich jedenfalls). Dann mache ich mir daraus. void* mit

    dyn_btfn_t dyn_btfn = (dyn_btfn_t)Marshal::GetFunctionPointerForDelegate(DynamicFunction).ToPointer();
    

    Irgendwie scheint es zu funktionieren und dann doch nicht. Ich kann den void* 200mal aufrufen und beim 201mal kracht es (zahlen frei erfunden!!!) und ich bekomme ganz seltsame effekte mit pufferüberläufen.
    Jetzt habe ich rausgefunden, dass mein void* auf 2 vollkommen unterschiedliche Adressen zeigt, wenn ich mir den void* vom delegate hole, oder wenn ich ihn direkt initialisiere mit

    dyn_btfn = Funktion;
    

    Auch wenn ich 2 delegates auf die gleiche Funktion habe und mir void* draus mache habe ich vollkommen verschiedene Adressen. Rufe ich mit dem void* erst das delegate auf und der ruft dann meine funktion auf??? Kann ich irgendwie feststellen worauf mein delegate zeigt??? Und warum passiert das komische zeug mit den pufferüberläufen???

    danke schonmal

    gruss



  • Wenn Du C++/CLI machst, dann überge bitte einen normalen C-Funktionspointer und nix mit C++/CLI!!!!! Das ist ja gerade der Trick, das dies einfach so geht!!!
    Bitte lass das ganze Marsahl-Zeugs weg!
    Sonst bräuchtest Du kein C++/CLI und könntest alles gleich in C# machen!



  • was mache ich wenn ich das zeug spaeter mit c# oder aehnlichem weiter benutzen will??? und nur den wrapper in c++/cli schreiben will???



  • Den Wrapper in C# verwenden



  • Sind wir heute wieder witzig???
    Ich frag doch nur, wie der delegate bloedsinn intern functioniert. Oder ob ich da irgendwas falsch machen.





  • Nochmal von Vorne:

    Ich möchte irgendwann in ferner Zukunft mal in C# oder was auch immer sagen können.

    delegate blabla = irgendeineFunktion
    

    irgendeineFunktion wird unmanaged Code sein. Der unmanaged Code soll nicht aufgerufen werden, er soll nur dazu dienen zu wissen wen ich aufrufen soll. Dann übergebe ich das delegate meinem wrapper und der macht dann ein void* draus. welcher dann auch aufgerufen wird.

    Also entweder bin ich schlecht im erklaeren, oder mein ansatz ist schon falsch.

    greetz



  • paindelux schrieb:

    Ich möchte irgendwann in ferner Zukunft mal in C# oder was auch immer sagen können.

    delegate blabla = irgendeineFunktion
    

    irgendeineFunktion wird unmanaged Code sein.

    Also, nochmals von vorne:
    Was für eine unmanaged Funktion hast Du? Ist sie in einer DLL und dort exportiert?
    Wenn nein, dann geht es nur mit einem Wrapper in C++/CLI (oder Du stellst diese Funktion als DLL-Export zur verfügung, dann greift wieder das erstere).

    Also, wenn Du die Funktion in keiner DLL hast, dann musst Du einen Wrapper in C*+/CLI schreiben, der dann diese Funktion aufruft.

    paindelux schrieb:

    Der unmanaged Code soll nicht aufgerufen werden, er soll nur dazu dienen zu wissen wen ich aufrufen soll.

    Wenn es nie aufgerufen wird, wozu brauchst Du es dann?

    paindelux schrieb:

    Dann übergebe ich das delegate meinem wrapper und der macht dann ein void* draus. welcher dann auch aufgerufen wird.

    Vergiss es... wie willst Du denn in C# irgendwas aufrufen?

    Dein Problem ist ein reines .NET -Problem und hat primär nichts mit C++/CLI zu tun. Wenn Du einen Pointer übergeben willst (das ist IMHO genau das was Du willst), dann verwende IntPtr als Datentyp und damit hast Du alle Probleme gelöst (bzw. vom Kenzept her gesehen wirst Du nie die Probelme losbekommen bzw. verlagest sie nur...)

    Geschweige denn, dass Dein Konzept hundsmiserabel ist.



  • Ich habe einen ganzen Pulk an unmanaged Code. Dieser Code muss intern Funktionen aufrufen. Diese Funktionen sind IN diesem Code und auch bekannt. So jetzt muss ich von ausserhalb nur sagen können welche funktionen er aufrufen soll. Was ich über ein delegate machen wollte, was aber wohl eine dumme idee war. Werde mir aber die geschichte mit IntPtr nochmal anschauen.

    danke



  • Häääää!????

    Du hast als z.B. als unmanaged Code:

    int Func1(int a, int b);
    bool Func2(float a, int b);
    

    Dann schreibst Du jetzt einfach in C++/CLI eine Managed Klasse, welche die Funktionen aufruft:

    namespace My
    {
      public ref class Wrapper
      {
        public:
          static int Function1(int a, int b)
          {
            return Func1(a, b);
          }
          static int Function2(float a, int b)
          {
            return Func2(a, b);
          }
      };
    }
    

    Und in C# verwendest Du diese Assembly dann so:

    My.Wrapper.Function1(1, 2);
    my.Wrapper.Function2(1.2, 4);
    


  • Was meinst du mit "von ausserhalb sagen welche funktion er aufrufen soll" ?

    Wo ist der Unterschied zu "von aussen aufrufen" ?



  • ich will das zeug weder aus c# noch aus c++/cli aufrufen. Ich will nur sagen was aufgerufen werden soll. Vielleicht so:

    c#

    funcPtr = eineFunction;
    wrapper(funcPtr);
    

    dann macht mein wrapper

    wrapper(delegate^ funcPtr)
    {
      internerFuncPtr = machVoidStern(funcPtr);
      unmanagedFunc(internerFuncPtr);
    }
    

    dann macht mein unmanaged Code

    unmanagedFunc(void* internerFuncPtr)
    {
      internerFuncPtr(); // aufruf
    }
    

    wobei eineFunction auch unmanaged ist. ich weiss nicht wie ich das noch erklaeren soll.
    So aehnlich wie wenn ich auf einen brief eine adresse draufschreib. ich bring den brief ja auch nicht selber weg sondern der postbote macht das.



  • Das ist ja wirklich kein guter Ansatz.

    Speichere deine Funktionszeiger besser in einer Datenstruktur und rufe sie mit einem Index oder über einen Namen auf.

    Ansonsten geht das was du suchst so

    IntPtr funcPtr = static_cast<IntPtr>(eineFunction);
    


  • merci vielmals war eine harte geburt und sorry wenn ich mich etwas unverstaendlich ausgedrueckt habe


Anmelden zum Antworten