_com_ptr_t(LPSTR) Konvertierungs-Konstruktor? WTF?



  • Gibt es eine Möglichkeit die Konvertierungs-Konstruktoren _com_ptr_t(LPSTR) und _com_ptr_t(LPWSTR) ohne gröbere Hacks loszuwerden? Bzw. wenigstens explicit zu machen?

    Ich hab' nämlich gerade einen "netten" Bug in einem unserer Programme gefunden. Vereinfachtes Beispiel:

    int GetSomething(CString recId); // TCHAR == wchar_t
    int GetSomething(ADODB::_RecordsetPtr rs);
    
    void Foo()
    {
        SomeStruct st;
        int something = GetSomething(st.someCharArray);
        // ...
    }
    

    Absicht: Aufruf von GetSomething(CString) . In Wirklichkeit leider: Aufruf von GetSomething(ADODB::_RecordsetPtr)
    Weil halt _ATL_CSTRING_EXPLICIT_CONSTRUCTORS , daher mag er aus dem narrow-char Array keinen CString machen (was soweit ja noch gut ist)... nur dann kommt der blöde _com_ptr_t(LPSTR) Konstruktor und statt einem Compilerfehler bekomm ich ne Exception zur Laufzeit.

    ARGH!

    Und da ich mich jetzt frage wo überall noch solche Fehler versteckt sind, würde ich diese beiden höchst fragwürdigen _com_ptr_t Konstruktoren gerne deaktivieren.

    ps: Das Projekt verwendet Visual Studio 2005... nachdem _com_ptr_t ja eine Compiler-Support Klasse ist das ja nicht ganz unwesentlich.



  • Wenn ich mir so anschaue, was _com_ptr_t so macht, käme ich irgendwie auf die Idee, mir da selber eine Klasse zusammenzufrickeln... Der operator bool, dann die ganzen impliziten Konvertierungen und Konstruktoren, für die mir kein Einsatzzweck einfällt...

    template<typename _Interface> bool operator!=(int null, const _com_ptr_t<_Interface>& p) 
    {
        if (null != 0) {
            _com_issue_error(E_POINTER);
        }
    
        return p != NULL;
    }
    

    Das ist wohl auch nicht mehr auf dem aktuellen Stand... 😃



  • Die Option steht leider nicht zur Verfügung.
    Das Projekt verwendet haufenweise COM Gedöns über #import , und #import verwendet halt nunmal _com_ptr_t und nicht boost::intrusive_ptr oder mein_noch_viel_coolerer_ptr .

    Wobei...

    Etwas in der Richtung könnte evtl. doch gehen.

    Dazu müsste man die von #import/_com_ptr_t verwendeten Hilfs-Makros hijacken. Das müsste fast gehen...
    Ich hatte aber auf eine weniger niederträchtige Lösung gehofft 🙂



  • Nun, aber es werden in den tlh's ja auch alle nötigen Daten generiert, um die Templateinstanziierung Deines besseren Zeigers zu einem Einzeiler verkommen zu lassen oder nicht?
    Ich habe damit noch nicht soviel gearbeitet (gerade erst am Dienstag das erste Mal, um ehrlich zu sein). Habe mich dann auch auch dem ganzen ATL-Gedöns vorbeigemogelt und IUnknown und IDispatch lieber per Hand implementiert, weil ich durch diese Bibliotheken echt nicht durchsteige...



  • Decimad schrieb:

    Nun, aber es werden in den tlh's ja auch alle nötigen Daten generiert, um die Templateinstanziierung Deines besseren Zeigers zu einem Einzeiler verkommen zu lassen oder nicht?

    Grundsätzlich... ja.

    Die generierten inline Funktionen verwenden halt die _com_ptr_t Typedefs als Returntyp.
    Wobei man das vermutlich über einen eigenen Conversion-Ctor erschlagen könnte (und nachdem keine 2 Conversion-Ctor verkettet werden dürfen wäre das auch kein echtes Problem).

    Hmmm....

    Muss ich mal drüber nachdenken, das könnte OK sein.
    Danke für den Vorschlag!


Anmelden zum Antworten