Pointer als property



  • Hallo,

    ich würde gerne in einer Komponenete einen Pointer als
    property declarieren.

    private:
    unsigned char *PData;
    __published:
    	__property unsigned char *Data = {read=PData,write=PData};
    

    Leider gibt es da die Fehlermeldung Kein zulässiger Typ.
    Ist das überhaupt möglich?



  • Möglich ja, aber schau dir mal genau deinen Code an 😉

    Allerdings verstehe ich nicht, warum du eine char*-Property verwenden willst. Was spricht denn z.B. gegen AnsiString?



  • Allerdings verstehe ich nicht, warum du eine char*-Property verwenden willst. Was spricht denn z.B. gegen AnsiString?

    Ich möchte der Componente einen Pionter auf ein unsigned char Array für
    die Datenspeicherung übergeben, es wird auch noch eine Eigenschaft
    DataCount geben.
    Meine Idee ist, eine Componente zur Datencommunication via Comport mit einem Controller.
    In dieser Componente gibt es ein Thread Object welches von der
    Componente intervalmässig instanziert wird.
    In diesem Thread werden dann n-Daten vom Com Port in das char Array dessen
    Pointer übergeben wurde gelesen, ist dieses geschehen wird es der Componente über ein Event mitgeteilt
    Draufhin wird ein Event OnData ausgelöst.

    Möglich ja, aber schau dir mal genau deinen Code an

    Wieso, ich instanziere einen unsigned char Pointer PData.
    Dann gibt es die Property des gleichen Typs.
    __property unsigned char *Data = {read=PData,write=PData};
    Was ist den da falsch?



  • aus der hilfe:

    Hinweis:

    In einem __published-Abschnitt sind weder Konstruktoren noch Destruktoren erlaubt. Dagegen sind Eigenschaften, intrinsische Pascal-Elemente oder von der VCL oder CLX abgeleitete Datenelemente, Elementfunktionen und Closures zulässig. Felder, die in einem __published-Abschnitt definiert werden, müssen von einem Klassentyp sein. Eigenschaften, die in einem __published
    -Abschnitt definiert werden, können keine Array-Eigenschaften sein. Der Typ einer Eigenschaft, die in einem __published-Abschnitt definiert wird, muß ein ordinaler Typ, ein Real-Typ, ein String-Typ, ein kleiner Mengentyp, ein Klassentyp oder ein Methodenzeigertyp sein.

    d.h. mache die eigenschaft doch private und stelle im public teil deiner kompo eine set/get-funktion bereit um den zugriff zu gewähren. deinen OnData-event kannst dann den zeiger auf diese daten übergeben und der user kann sie auslesen...



  • Was Du hingegen schon machen kannst wäre:

    __published:
            __property int DataCount = {read = getDataCount};
            __property unsigned char Data[int Index] = {read = getData, write = setData};
    private:
            int getDataCount();
            unsigned char getData();
            void setData(unsigned char Value);
    

    Wie Du die Daten dann tatsächlich speicherst, ist Deine Sachen.

    Gruß,

    Alexander



  • das ist natürlich auch ne möglichkeit...

    allerdings wird dann bei jedem element zugriff (bei jeden einzelnen zeichen) auf das array immer die get/set-funktion aufgerufen, was sich extrem auf die geschwindigkeit niederschlägt und deinen ganzen programmablauf verlangsamt.

    das wird z.b. sehr schön bei der Pixels-Eigenschaft von TCanvas deutlich.



  • Beim COM-Port spielt die Geschwindigkeit vielleicht nicht dieselbe Rolle wie bei Grafikoperationen.

    Gruß,

    Alexander



  • Hier könnte man die Get/Set-Methoden inline machen. Da dürften dann auch keine Geschwindigkeitsnachteile auftreten.
    GetPixel ist hier eher ein schlechtes Beispiel, da hier ein wenig mehr gemacht wird als nur auf ein Pixel zuzugreifen (es wird auch auf Windows::GetPixel zugegriffen).



  • Oder so:

    typedef unsigned char *TPData;
    
    private: 
      TPData PData; 
    __public: 
        __property TPData Data = {read=PData,write=PData};
    

    Aber Vorsicht!!!

    - im Constructor PData = NULL;

    - vor schreiben in PData testen, ob der Zeiger gültig ist!!!
    Sonst 😃 😃 😃

    - Wehe, wnn der Puffer zu klein ist!!!

    NIMM LIEBER AnsiString



  • typedef unsigned char *TPData;
    
    private:
      TPData PData;
    __public:
        __property TPData Data = {read=PData,write=PData};
    

    Dafür brauche ich aber nicht vorher einen Datentyp unsigned char *TPData definieren, das geht auch direkt.

    private:
    unsigned char *Pdata;
    TTimer *Timer;
    void __fastcall TimerEvent(TObject *Sender);
    protected:
    public:
    	__property unsigned char *data = {read=Pdata,write=Pdata};
    	__fastcall TThreadCom(TComponent* Owner);
    __published:
    

    Hier könnte man die Get/Set-Methoden inline machen.
    Da dürften dann auch keine Geschwindigkeitsnachteile auftreten.

    Was genau bedeutet inline und warum wird wird das ganze dann schneller?

    __inline void __fastcall SetIMPosValue(int NewPosValue); //Setter
    
    //---------------------------------------------------------------------------
    __inline void __fastcall TInstrument::SetIMPosValue(int NewPosValue)
    {
         IMPosValue = NewPosValue;
         Repaint();
    }
    

    Gibt beim erzeugen keine Fehlermeldung, benutze ich die Komponenete
    kommt -unresolved externel-



  • Hallo,

    Lass einfach die Unterstriche vor inline weg. Alternativ kann man auch auf inline ganz verzichten und einfach auch die Definition der Funktion in den Header schreiben. All dies ist allerdings keine Garantie dafür, dass die Funktion wirklich inline wird. Das entscheidet dann der Compiler.
    In deinem Fall macht es aber wenig Sinn die Funktion inline zu machen, da du Repaint() aufrufst. Diese Funktion braucht soviel Zeit, dass der eventuelle Geschwindigkeitsgewinn einer inline-Funktion vernachlässigbar ist.



  • Da die Funktion Repaint() soviel Zeit verbraucht, spricht dann was dagegen
    meine Funktion die z.B. die Grafik neu zeichnet direkt vom Setter auszuführen
    anstatt über die Methode Paint.
    Funktioniert dann auch DoubleBuffered noch.


Anmelden zum Antworten