Delphi EXE und C++ DLL



  • Hallo!

    Hab Probleme bei der Verbindung einer C++ DLL und einer Delphi EXE.

    In der C++ DLL hab ich in etwa folgendes, wobei EXPORT_CALL dafür sorgt dass die Funktion korrekt exportiert wird.

    Interface1* EXPORT_CALL Get1();
    
    class Interface1
    {
      virtual void __stdcall register2(Interface2* interf2)=0;
    };
    
    class Interface2
    {
      virtual void __stdcall foo()=0;
    };
    

    Soweit sogut.
    Mit einer C++ EXE kann ich problemlos die Funktion aufrufen, welche mir dann eine Instanz vom Typ InterfaceXY* gibt. Dann erstelle ich in der EXE eine Instanz vom Typ Interface2 und übergebe das der DLL.
    Also so in der Art:

    Interface2* interf2=new NonAbstractClass2();
    Interface1* interf1=Get1();
    interf1->register2(interf2);
    

    In der DLL wiederum wird dann mit dem übergebenen interf2 gearbeitet.
    Das klappt alles problemlos.

    Von einer Delphi EXE kann ich auch die Funktion Get1() aufrufen.
    Ich kann auch eine Instanz vom Typ Interface2* anlegen.
    Und ich kann mich auch mit interf1->register2(interf2) registrieren.
    Sobald ich aber von der C++ DLL auf die übergebene interf2 Instanz zugreifen möchte, also so in der Art interf2->foo(), dann krachts!
    C++ wirft eine Fehlermeldung aus, dass es Probleme mit dem Stackpointer gibt:
    "The value of ESP was not properly saved across a function call..."

    Nun habe ich aber genau aufgepasst, dass ich die Calling Convention einhalte, ich hab bei den Methoden der Interfaces immer stdcall verwendet.

    Konkret fallen mir noch folgende Möglichkeiten ein:
    +Name-Mangling bei den Klassen (also diese C++ Benamsung von Funktionen): Sollte aber kein Problem sein weil es sich ja um abstrakte Klassen handelt, und letztendlich nur Zeiger auf die Funktionen gespeichert werden (vtable und das Zeugs).

    +Delphi Klassen leiten meines Wissens immer von TObject ab. Vielleicht kommt C++ damit nicht klar, dass ich mit interf1->register2(interf2) ein Objekt übergebe, welches auch von TObject ableitet?

    +Vielleicht doch irgendwo calling convention falsch? Wobei ich das 1000mal geprüft habe.

    Sonst noch Ideen?
    Mir wäre der objektorientierte Ansatz ehrlich gesagt schon lieber, da es die Sache ungemein vereinfacht.
    Wenn es denn sein muss kann ich natürlich komplett auf C Funktionen und "alte" Datentypen zurückgreifen, dass würde aber das Design schon ziemlich unschön machen.

    P.S.: Hab den Code gerade nicht vor mir, d.h. sind vllt. ein paar Tippfehler drinnen, lasst euch davon nicht stören.
    Dem Forum zuliebe habe ich, auch wenn ich von Delphi gesprochen habe, C++ Code verwendet.



  • kann es sein, dass das __stdcall bei den Memberfunktionen nicht ok ist?
    Dass dort ein thiscall hinmuss? Wäre jedenfalls blöd, denn Delphi kennt kein thiscall.



  • Klassen kann man nicht außerhalb vom *gleichen* C++ Compiler verwenden.



  • Jochen Kalmbach schrieb:

    Klassen kann man nicht außerhalb vom *gleichen* C++ Compiler verwenden.

    Das ist schade.

    Mmmh, dann wäre wohl der einzige Weg, in der EXE von der DLL zu bestimmten Ereignissen benachrichtigt zu werden, indem ich den Zeiger auf eine Callbackfunktion übergebe?
    Und eben schön brav bei reinem C bleiben.



  • Genau... eben so wie es die WinAPI auch macht 😉



  • Jochen Kalmbach schrieb:

    Genau... eben so wie es die WinAPI auch macht 😉

    ok, danke!



  • Oder du machst COM Klassen, das wär objektorientiert, aber nicht ganz so trivial.


Anmelden zum Antworten