Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Dyn. Record & Array, PChar treffen auf DLL's (https://www.delphipraxis.net/117467-dyn-record-array-pchar-treffen-auf-dlls.html)

Desmulator 18. Jul 2008 15:15


Dyn. Record & Array, PChar treffen auf DLL's
 
Hoi,
nun, wie die Überschrift schon sagt, habe ich ein paar Fragen zu besonderen Datentypen in Verbindung mit DLLs.

Als erstes kommt der in Delphi bekannte VariantRecord, der sein Inhalt ändern kann, je nach dem Wert eines bestimmten Eintrags.
Die ganze Angelegnheit sieht so aus:
Delphi-Quellcode:
  TKeyWord = record
    Name : PChar;
    CaseIntensiv : Boolean;
  end;

  TCharRange = record
    Range : array of Char;
    CaseIntensiv : Boolean;
  end;

  TParentheses = record
    StartTag : PChar;
    EndTag : PChar;
    CaseIntensiv : Boolean;
  end;
 
  TToken = record
    ID : Cardinal;
    Prioiorty : Cardinal;
    TokenType : TTokenType;
    case TokenType : TTokenType of //hier ist der VariantTeil
      ttKeyWord : ( Data : TKeyWord ); //Jenachdem wie TokenTyp steht
      ttCharRange : ( Data : TCharRange ); //Wird der entsprechende Record
      ttParentheses : ( Data : TParentheses ); //hinzu gefügt
  end;
Frage, ist sowas alls DLL Export/Import möglich, oder bestehen da schwierigkeiten in anderen Programmiersprachen?
Wenn ja, was gibt es für alternative Möglichkeiten.

Jetzt komm ich zu der Dynamischen Array. Gibt es eine Möglichkeit diese innerhalb der DLL zu speichern, da ihre Elementanzahl, wie gesagt dynamisch ist.

Delphi-Quellcode:
  TCharRange = record
    Range : array of Char; //Hier können beliebig viele Chars enthalten sein.
    CaseIntensiv : Boolean;
  end;
Das Problem ist, wenn eine Programmfunktion, die diese Array übergabe, termieniert wird, wird auch das array aus dem speicher entfernt, daher suche ich nach einer Möglichkeit dieses Array in einen anderen Speicherbereich zu verschieben.

Das gleiche Problem besteht auch bei PChar/PAnsiChar , wenn hier die Funktion terminiert wird, wird auch deren speicherplatz gelöscht, daher auch die daten sind verloren und mein gespeicherter Pointer zeigt auf nichts.

Mfg
Desmu :stupid:

nicodex 18. Jul 2008 16:21

Re: Dyn. Record & Array, PChar treffen auf DLL's
 
Zitat:

Zitat von Desmulator
Jetzt komm ich zu der Dynamischen Array. Gibt es eine Möglichkeit diese innerhalb der DLL zu speichern, da ihre Elementanzahl, wie gesagt dynamisch ist.

Delphi-Quellcode:
  TCharRange = record
    Range : array of Char; //Hier können beliebig viele Chars enthalten sein.
    CaseIntensiv : Boolean;
  end;

Delphis Dynamische Arrays sind compilerspezifisch und der Aufbau ist offiziell nicht dokumentiert (soweit ich weiß).

Range ist ein Zeiger, welcher auf das erste Element zeigt (in deinem Fall also ein PChar). Wenn Range nil ist, dann ist das Array als leer (Länge 0) zu interpretieren. Vier Byte vor dem ersten Element befindet sich ein 32-Bit Integer im Speicher, in welchem die Länge oder der Index des letzten Elements steht (bin mir gerade nicht sicher... kann man im CPU-Fenster nachlesen, wenn man Length() verwendet).

Die Implementation dynamischer Arrays könnte jederzeit geändert werden - theoretisch (praktisch gibt es keinen Grund dafür, außer man hat einen 64-Bit Compiler).

ps: Alternative wäre, den Zeiger auf das erste Element und die Länge getrennt zu übergeben.

Apollonius 18. Jul 2008 17:44

Re: Dyn. Record & Array, PChar treffen auf DLL's
 
Außerdem gibt es bei dynamischen Arrays Referenzzählung: 8 Byte vor dem ersten Element befindet sich ein Integer, der die Anzahl der gültigen Referenzen anzeigt.

Variante Records sind überhaupt kein Problem. In C kann man dafür Unions verwenden, in anderen Sprachen muss eventuell ein bisschen getrickst werden, falls sie dieses Konzept nicht unterstützen, aber auch das ist nicht schwierig.

Bei dynamischen Arrays kommt es darauf an, was du in der DLL mit ihnen machen willst. Du kannst aus DLLs auf keinen Fall die Länge ändern, aber sowohl Lesen als auch Schreiben einzelner Elemente sollte funktionieren.

nicodex 18. Jul 2008 18:04

Re: Dyn. Record & Array, PChar treffen auf DLL's
 
Zitat:

Zitat von Apollonius
[...] als auch Schreiben einzelner Elemente sollte funktionieren.

Was man tunlichst lassen sollte, falls der von dir erwähnte Referenzzähler nicht 1 ist ;)

Apollonius 18. Jul 2008 19:54

Re: Dyn. Record & Array, PChar treffen auf DLL's
 
Aber das gilt auch in Delphi. Bei dynamischen Arrays ist die Referenzzählung nicht ganz so konsequent wie bei Strings umgesetzt - es gilt kein Copy-On-Write, sondern alle Referenzen sind betroffen.

Desmulator 19. Jul 2008 19:43

Re: Dyn. Record & Array, PChar treffen auf DLL's
 
Okay also lasse ich mir bei einer dynamischen Array einfach die Länge mit übergeben, sodass ich weiß, wieviel Einträge ich ab Pointer ablesen muss.

Wie mache ich es beim String, bzw. PChar? Er ist im Prinzip nichts anderes als eine dynmaische Array. Ist hier auch die Länge nötig oder ist der Integer vor dem Pointer immer vorhanden?

Und danke für eine Antworten :stupid:

Edit, @Strings: Ich könnte ja auch solange einlesen bis ich auf das 0 Byte Char treffe 8)

Apollonius 19. Jul 2008 20:33

Re: Dyn. Record & Array, PChar treffen auf DLL's
 
PChar speichert keine Länge, aber sie lässt sich durch das #0-Zeichen ablesen (Funktion StrLen). Ein String ist ein bisschen mehr als ein PChar (solange er nicht nil ist - das entspricht einem #0-PChar) - wenn du einen String erhältst, kannst du ihn ohne Probleme als PChar behandeln. Zusätzlich werden aber, solange der String nicht nil ist, wie beim dynamischen Array Referenzzähler und Länge vor dem Anfang der Daten gespeichert.


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:16 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz