Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Probleme mit WideChar (https://www.delphipraxis.net/12868-probleme-mit-widechar.html)

Canton 5. Dez 2003 13:24


Probleme mit WideChar
 
Hallo erstmal,

ich habe da ein kleines problem ich Versuche einem WideChar einen String zu zuweisen.
Diese funktioniert auch wunderbar wenn ich es einzeln mache. Da ich aber Beide Variablen dynamisch habe versuche ich es über eine Schleife. Was für mich eine ziemlich verwirrende Wirkung hat da nach dem zweiten index er damit beginnt mir sowohl den aktuelle index zu beschreiben und den ersten (also 0)
aber genug der langen worte hier erstmal der Quelltext:

Delphi-Quellcode:
procedure AddItemsClick;
var
  i, y, x, z, WertItemID : integer;
  HRes    : HRESULT;
  sItemID : array of pWideChar;
  ItemDef : array of OPCITEMDEF;
  Results : POPCITEMRESULTARRAY;
  Errors  : PResultList;
  Test : array of String;
begin
  AnzahlEintraege:=0;//erstam anzahl einträge auf 0 setzten
  WertItemID:=0; //auch erstmal auf 0 setzen
//Benötigte länge der Arrays ermitteln
  for x:=low (NewItems) to high (NewItems) do
  Begin
     for y:=low(NewItems[x]) to high (NewItems[x]) do
     Begin
        AnzahlEintraege:=AnzahlEintraege+Length(NewItems[x,y])//Um anzahl an Einträgen zu ermitteln
     end;
  end;

  SetLength(ItemDef, AnzahlEintraege);
  SetLength(sItemID, AnzahlEintraege);

  for x:=low(NewItems) to high (NewItems) do
  Begin
     for y:=Low(NewItems[x]) to high (NewItems[x]) do
     Begin
        for z:=Low(NewItems[x,y]) to high(NewItems[x,y]) do
        Begin
             SItemID[WertItemID]:=pWideChar(WideString(NewItmes[x,y,z]));
             WertItemID:=WertItemID+1;
        end;
     end;
  end;
So wie ihr vielleicht gesehen habt ist Die Variable NewItems(die globala als array of array of array of String) definiert ist ein Mehrfachdimensonales Array. Und dadurch das sich x,y,z in den drei schleifen Ständig änder so Brfürchte ich mal das die Pointer zu diesen Strings sich ändern und sich dadurch die Werte Verändern. Aber so recht habe ich das Mit den Null-Terminirten Strings nicht verstanden. (Da die gleichen Schleifen auch wunderbar woanders tun allerdings schreiben sie da auch auf "Normale" Strings).
Habe auch schon Versucht mir erst nen TempString zu bilden der die ganzen Werte nur in einer Dimmension fast (also nur array of String) und diese dann dem WideChar zuweise aber das hat auch nicht funktioniert.

Also hat jemand ne Idee? Ich bin langsam kurz vorm :wall:

Tiefflieger 5. Dez 2003 18:27

Re: Probleme mit WideChar
 
for - schleifen laufen meistens intern von hinten nach vorne, nur wenn schaltjahr ist und die venus im westen steht tunse das, was sie sollen - also lieber eine while schleife benutzen, wos auf die reihenfolge ankommt:

Delphi-Quellcode:
x := low;
while (x <= high (NewItems)) do
  Begin
    inc(x);
  end;
ich glaube, dass man das auch unter den compiler-optionen abschalten kann, aber ich finds grad nicht...

jbg 6. Dez 2003 00:42

Re: Probleme mit WideChar
 
Zitat:

Zitat von Tiefflieger
for - schleifen laufen meistens intern von hinten nach vorne, nur wenn schaltjahr ist und die venus im westen steht tunse das, was sie sollen - also lieber eine while schleife benutzen, wos auf die reihenfolge ankommt

So ein Unsinn. Die Schleife mag zwar intern rückwärts laufen, dafür wird aber der benutzte temporäre Zeiger erhöht, was auf das gleiche hinausläuft. Allein der Debugger kommt damit nicht klar und zeigt eben den Inhalt der Zählvariable an, die halt rückwärts läuft, obwohl die Schleife im gesamten betrachtet vorwährts läuft.


Zitat:

SItemID[WertItemID]:=pWideChar(WideString(NewItmes[x,y,z]));
Das ist sehr gefährlich. Ein WideString ist intern nichts anderes als ein PWideChar. Bei dieser Zuweisung legst du nun die Adresse eines temporären WideStrings in SItemID[] ab. Diese Adresse wird, da sie temporär ist, vom weiteren Code überschrieben und ggf. auch freigegeben. Daraus resultieren dann falsche Daten und Schutzverletzungen.

Canton 15. Dez 2003 08:14

Re: Probleme mit WideChar
 
das mit dem widechar würde ich ja auch gerne sein lassen aber ich habe das prob das ne funktion bzw procedure in ner bibliothek genau diese variable braucht. wenn ich es statisch erzeuge also die werte ohne schliefe zuweise funktioniert es wunder bar. aber ich möchte es gern dynamisch erzeugen. irgend ne idee??

jbg 15. Dez 2003 09:03

Re: Probleme mit WideChar
 
Du könntest anstatt PWideChar einfach WideString schreiben. Dann kann der Compiler seine Compiler-Magic richtig ausspielen. Das geht da WideString nichts anderes als ein PWideChar ist.

Der Compiler ruft bei PWideChar(MyWideString) folgende Funktion auf:
Delphi-Quellcode:
function _WStrToPWChar(const S: WideString): PWideChar;
const
  EmptyString = '';
begin
  if Pointer(S) = nil then
    Result := EmptyString // nur wenn WideString = '' => Pointer(S) = nil => liefere #0
  else
    Result := Pointer(S);
end;

Canton 15. Dez 2003 13:18

Re: Probleme mit WideChar
 
hmmm hab ich dich da jetzt falsch verstanden? wenn ich das pwidechar wech lasse (so wie unten)bringt er mir die fehlermeldung inkompatible typen also widestring und pwidechar

Delphi-Quellcode:
SItemID[WertItemID]:=WideString(NewItmes[x,y,z]);
Zitat:

Adresse eines temporären WideStrings in SItemID[] ab. Diese Adresse wird, da sie temporär ist, vom weiteren Code überschrieben und ggf. auch freigegeben. Daraus resultieren dann falsche Daten und Schutzverletzungen.
kann ich die varibale dann nach dem beschreiben irgendwie schreibschützen? so das sie von nirgens wo anderes ausversehen wieder beschrieben werden kann?

patty 15. Dez 2003 13:43

Re: Probleme mit WideChar
 
Zitat:

Zitat von Canton
hmmm hab ich dich da jetzt falsch verstanden? wenn ich das pwidechar wech lasse (so wie unten)bringt er mir die fehlermeldung inkompatible typen also widestring und pwidechar

Delphi-Quellcode:
SItemID[WertItemID]:=WideString(NewItmes[x,y,z]);

Die Fehlermeldung ist korrekt - sowas nimmt Delphi ganz genau. Ein PWideChar ist ein Zeiger auf ein WideChar. Das nullterminierte String entsteht lediglich dadurch, dass der Zeiger intern solange erhoeht wird, bis ein CHR(0) kommt. Du musst also im Endeffekt bei der Wertzuweisung einen Zeiger auf das erste Zeichen des Strings uebergeben:

Delphi-Quellcode:
SItemID[WertItemID] := @WideString(NewItmes[x,y,z])[1];
Das sollte gehen [ohne es jetzt grad testen zu koennen].


Zitat:

Zitat von Canton
kann ich die varibale dann nach dem beschreiben irgendwie schreibschützen? so das sie von nirgens wo anderes ausversehen wieder beschrieben werden kann?

Variablen kann man generell nicht schreibschuetzen; lediglich auf den Gueltigkeitsbereich hat man Einfluss. Deklariere eine Variable immer so, dass sie gerade so den erforderlichen Gueltigkeitsbereich hat (z.B. als Private-Feld in einer Klasse) und greife ggf. mit Funktionen/Methoden darauf zu.

Canton 15. Dez 2003 14:11

Re: Probleme mit WideChar
 
hmm schade das tut immer noch also zuweisen kann ich es so schon aber es hat immer noch den gleichen unerwünschten effekt.

hier mal meine schliefe die so ein mist baut:

Delphi-Quellcode:
for i:=0 to AnzahlEintraege-1 do
Begin
   SItemID[i]:=@WideString(Test[i])[1]; //(schon extra 1dimensional gehalten)
end;
das eindimensionale array wird über schleifen beschrieben die var test ist array of string

schleifendurchlauf:
i=0 SItemID = '0'
i=1 SItemID = '0' , '1' //bis hier tut es wunderbar
i=2 SItemID = '2' , '1', '2'
i=3 SItemID = '2' , '3', '2', '3'
i=4 SItemID = '4' , '3', '4', '3'

usw. in SItemID stehen natürlich nicht zahlen ist nur als Beispiel um zu zeigen was die schliefe komischer weise macht sprich 0, 1,... stehen für einen String bzw WideString
Was mich dabei jetzt absolut wundert ist das der schleifenzähler eindeutig auf z.B. 4 steht und er trozdem SItemID[1] beschreibt obwohl der Index ja über i definiert ist und er so nur den index 4 beschreiben dürfte.

jbg 15. Dez 2003 17:21

Re: Probleme mit WideChar
 
Zitat:

Zitat von Canton
hmmm hab ich dich da jetzt falsch verstanden?

Du musst auch das Array in array of WideString ändern.

patty 15. Dez 2003 17:45

Re: Probleme mit WideChar
 
Aber sollte das String-Array nicht gerade in ein PWideChar-Array umgewandelt werden? Genau das sollte diese Schleife naemlich tun. Der Fehler steckt offenbar woanders; vielleicht bei der Ausgabe... Oder machst du noch irgendwas mit dem PWideChar-Array?

Probier mal fuer die Ausgabe folgenden Code:

Delphi-Quellcode:
for i := 0 to AnzahlEintraege-1 do Application.MessageBox(@AnsiString(SItemID[i])[1], 'Debug');
Ansonsten stimmen evtl. die Strings vorher schon nicht...?


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:25 Uhr.
Seite 1 von 2  1 2      

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