Visual Studio 2005 und vc7



  • dann ist das aber ein schlechtes plugin system.
    wo liegt das problem?
    ist new/delete anders impl.
    oder sind in den interfaces nicht nur basis typen verwendet?



  • Tja das kann sein - Das System basiert auf der ACDK-Bibliothek, vermutlich liegt da der Hase im Pfeffer. Es ist jedenfalls müßig mit dem 8er Kompiler, ich habe seit über 6 Wochen Probleme, die nicht in den Griff zu bekommen sind und mit dem 7.1 nicht auftauchen.



  • Möglicherweise ist mir zumindest *eine* Lösung eingefallen - Was würde passieren, wenn ich ein Makefile Projekt in VS 2005 erstelle und im Makefile den 7.1 Compiler verwende?



  • Du könntest dir das Leben einfacher machen, indem du das Projekt mit Code::Blocks importierst. Es unterstützt viele verschiedene Compiler, und man kann sogar innerhalb eines Projektes Build-Ziele haben, denen unterschiedliche Compiler zugeordnet sind. Im Normalfall werden die installierten Compiler automatisch erkannt.



  • Oder Du könntest versuchen die ACDK-Bibliothek selbst mit VC8.0 zu kompilieren. Ist ja auf sourceforge gehostet und der Source kann heruntergeladen werden.



  • simon.gysi schrieb:

    Oder Du könntest versuchen die ACDK-Bibliothek selbst mit VC8.0 zu kompilieren. Ist ja auf sourceforge gehostet und der Source kann heruntergeladen werden.

    100% ACK!

    Man darf keine Bibliotheken (LIBs) mischen, wenn hier unterschiedliche Compiler verwendet wurden. Ausnahme: Einzig und alleine Import LIBs.

    - Bei DLLs darf in keinem Fall Cross-Module-Allocation verwendet werden. new in der DLL delete in EXE oder umgekehrt.
    - Es dürfen niemals STL Objekte über das DLL Interface getauscht werden...



  • - Es dürfen niemals STL Objekte über das DLL Interface getauscht werden...

    Nicht nur STL Objekte, sondern generelll Objekte, deren Impl. geändert haben könnte, oder hab ich da was falsch verstanden?



  • simon.gysi schrieb:

    - Es dürfen niemals STL Objekte über das DLL Interface getauscht werden...

    Nicht nur STL Objekte, sondern generelll Objekte, deren Impl. geändert haben könnte, oder hab ich da was falsch verstanden?

    Nein! Ich wollte es nicht zu weit einschränken.
    Ich tausche oft (ähnlich wie bei COM Interfacezeiger aus). Wobei die DLL Module jier ganz unterschiedlcihe Compiler haben dürfen.

    Soetwas wäre erlaubt.

    Dito Zeiger uas dem Global-Heap und Local-Heap, die können wahlfrei allokiert und freigegeben werden egal welches Modul dies tut.

    Objekte, die auf PODs aufbauen (wie beim SDK) gehen auch...

    Ich habe mir schon immer mal vorgenommen dazu was zu schreiben, nur ist das vermutlich keine ein Seiten Artikel... 😉



  • Martin Richter schrieb:

    - Bei DLLs darf in keinem Fall Cross-Module-Allocation verwendet werden. new in der DLL delete in EXE oder umgekehrt.

    Das sollte eigentlich kein Problem sein, wenn das Interface einen virtuellen Destruktor verwendet. Was der C++-Standard genau dazu sagt, weiß ich nicht, aber in C++Builder gibt der virtuelle Destruktor den Speicher frei.
    Und auf ein nacktes new verzichtet man gewöhnlich ohehin, wenn man mit Factories arbeitet.

    Martin Richter schrieb:

    - Es dürfen niemals STL Objekte über das DLL Interface getauscht werden...

    Genau für diesen Zweck hatte ich mir mal einen kleinen generischen Iterator-Wrapper geschrieben, der mit ein bißchen Template-Magie die Bedienung und Freigabe eines beliebigen Iterators übernehmen konnte. Für Modulinterfaces wunderbar geeignet.

    Martin Richter schrieb:

    Dito Zeiger uas dem Global-Heap und Local-Heap, die können wahlfrei allokiert und freigegeben werden egal welches Modul dies tut.

    Aber nur, wenn man direkt die WinAPI-Funktionen benutzt und nicht new/delete.



  • apoc333 schrieb:

    Ich will den Compiler und Linke in der Version 7.1 nehmen (also den aus VS 2003). Ich muss leider 7.1 nehmen, da ich ein Plugin für eine kommerzielle Anwendung entwickel, die mit 7.1 gebaut wurde. Wenn ich den 8.0 (VS 2005) nehme bekomme ich z.B. allocation errrors.
    Prinzipiell ist es natürlich kein Problem mit VS 2003 zu arbeiten, ich bin aber aus anderen Projekten 2005 gewohnt.

    In VS 2003 gabs bei der Codeerstellung als Laufzeitbibliothek "Singlethread(/ML)" zu wählen.
    VS 2005 kennt nur noch "Multithreaded(/MT)", daher warscheinlich auch die allocation errrors beim Verwenden von VS 2005.



  • audacia schrieb:

    Martin Richter schrieb:

    - Bei DLLs darf in keinem Fall Cross-Module-Allocation verwendet werden. new in der DLL delete in EXE oder umgekehrt.

    Das sollte eigentlich kein Problem sein, wenn das Interface einen virtuellen Destruktor verwendet. Was der C++-Standard genau dazu sagt, weiß ich nicht, aber in C++Builder gibt der virtuelle Destruktor den Speicher frei.
    Und auf ein nacktes new verzichtet man gewöhnlich ohehin, wenn man mit Factories arbeitet.

    Das ist in anderen Compilern nicht möglich, dort wird die die Funktion des Modules verwendet in der der Code liegt.
    D.h. z.B. statische Bindung der DLL, DLL-CRT in der EXE und es kracht ohne Ende.

    audacia schrieb:

    Martin Richter schrieb:

    Dito Zeiger uas dem Global-Heap und Local-Heap, die können wahlfrei allokiert und freigegeben werden egal welches Modul dies tut.

    Aber nur, wenn man direkt die WinAPI-Funktionen benutzt und nicht new/delete.

    [/quote]

    Das habe ich doch geschrieben.



  • Martin Richter schrieb:

    Das ist in anderen Compilern nicht möglich, dort wird die die Funktion des Modules verwendet in der der Code liegt.

    Bedauerlich 😞
    Dann muß das Factory-Framework eben eine Destroy-Funktion bereitstellen.

    audacia schrieb:

    Das habe ich doch geschrieben.

    Stimmt; bei genauerem Lesen fällt mir das auch auf 🙄
    Ich hatte da irgendwie reininterpretiert, daß man new und delete benutzen könnte, wenn sie mittels dieser WinAPI-Funktionen implementiert wären.



  • audacia schrieb:

    Martin Richter schrieb:

    Das ist in anderen Compilern nicht möglich, dort wird die die Funktion des Modules verwendet in der der Code liegt.

    Bedauerlich 😞
    Dann muß das Factory-Framework eben eine Destroy-Funktion bereitstellen.

    Genau. 100% ACK!
    Ein Factory Modell ist genau dass, mit dem man ein komplexeres Objektmodel mit DLLs entwerfen muss. Die Factory sorgt für Erzeugung (Allokation) und Zerstörung (Deallokation) der Objekte.



  • Martin Richter schrieb:

    Das ist in anderen Compilern nicht möglich, dort wird die die Funktion des Modules verwendet in der der Code liegt.

    Hmm, ich habe es zwischenzeitlich auch mit MinGW und mit Visual C++ 2008 getestet, und in beiden wird der operator delete vom Destruktor ausgeführt:

    In Visual C++:

    MyImpl::`scalar deleting destructor':
    00411700  push        ebp  
    00411701  mov         ebp,esp 
    00411703  sub         esp,0CCh 
    00411709  push        ebx  
    0041170A  push        esi  
    0041170B  push        edi  
    0041170C  push        ecx  
    0041170D  lea         edi,[ebp-0CCh] 
    00411713  mov         ecx,33h 
    00411718  mov         eax,0CCCCCCCCh 
    0041171D  rep stos    dword ptr es:[edi] 
    0041171F  pop         ecx  
    00411720  mov         dword ptr [ebp-8],ecx 
    00411723  mov         ecx,dword ptr [this] 
    00411726  call        MyImpl::~MyImpl (411096h)
    0041172B  mov         eax,dword ptr [ebp+8] 
    0041172E  and         eax,1 
    00411731  je          MyImpl::`scalar deleting destructor'+3Fh (41173Fh) 
    00411733  mov         eax,dword ptr [this] 
    00411736  push        eax  
    00411737  call        operator delete (4110AAh) ; <---
    0041173C  add         esp,4 
    0041173F  mov         eax,dword ptr [this] 
    00411742  pop         edi  
    00411743  pop         esi  
    00411744  pop         ebx  
    00411745  add         esp,0CCh 
    0041174B  cmp         ebp,esp 
    0041174D  call        @ILT+375(__RTC_CheckEsp) (41117Ch) 
    00411752  mov         esp,ebp 
    00411754  pop         ebp  
    00411755  ret         4
    

    Der verwendete Quelltext:

    class MyIntf
    {
    public:
        virtual ~MyIntf (void) {}
    };
    
    class MyImpl : public MyIntf
    {
    public:
        virtual ~MyImpl (void) {}
    };
    
    int main (void)
    {
        MyIntf* mi = new MyImpl;
        delete mi;
    }
    

    Es sieht so aus, als wäre das doch gemeinhin so implementiert.
    Könnte mal jemand das im Standard nachschlagen?



  • audacia schrieb:

    Könnte mal jemand das im Standard nachschlagen?

    Das habe ich mittlerweile selbst getan. Dort steht in §12.4.11:

    ISO 14882 schrieb:

    At the point of definition of a virtual destructor (including an implicit definition (12.8)), non-placement operator delete shall be looked up in the scope of the destructor’s class (3.4.1) and if found shall be accessible and unambiguous. [Note: this assures that an operator delete corresponding to the dynamic type of an object is available for the delete-expression (12.5).]

    Demnach implementieren das MSVC, GCC und BCC standardkonform, und es ist legitim, ein in einem anderen Modul dynamisch erstelltes Objekt mit virtuellem Destruktor mit delete freizugeben. Ein Factory-Delete ist somit überflüssig.


Anmelden zum Antworten