AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Dyn. Record & Array, PChar treffen auf DLL's
Thema durchsuchen
Ansicht
Themen-Optionen

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

Ein Thema von Desmulator · begonnen am 18. Jul 2008 · letzter Beitrag vom 19. Jul 2008
Antwort Antwort
Benutzerbild von Desmulator
Desmulator

Registriert seit: 3. Mai 2007
Ort: Bonn
169 Beiträge
 
#1

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

  Alt 18. Jul 2008, 16:15
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
Lars
There are 10 kinds of people in the world:
those who get binary, and those who don’t.
  Mit Zitat antworten Zitat
Benutzerbild von nicodex
nicodex

Registriert seit: 2. Jan 2008
Ort: Darmstadt
286 Beiträge
 
Delphi 2007 Professional
 
#2

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

  Alt 18. Jul 2008, 17:21
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.
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#3

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

  Alt 18. Jul 2008, 18:44
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.
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
Benutzerbild von nicodex
nicodex

Registriert seit: 2. Jan 2008
Ort: Darmstadt
286 Beiträge
 
Delphi 2007 Professional
 
#4

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

  Alt 18. Jul 2008, 19:04
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
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#5

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

  Alt 18. Jul 2008, 20:54
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.
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
Benutzerbild von Desmulator
Desmulator

Registriert seit: 3. Mai 2007
Ort: Bonn
169 Beiträge
 
#6

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

  Alt 19. Jul 2008, 20:43
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

Edit, @Strings: Ich könnte ja auch solange einlesen bis ich auf das 0 Byte Char treffe 8)
Lars
There are 10 kinds of people in the world:
those who get binary, and those who don’t.
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#7

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

  Alt 19. Jul 2008, 21:33
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.
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:56 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz