AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Strings in Delphi in DLL

Ein Thema von Blatt · begonnen am 21. Okt 2010 · letzter Beitrag vom 21. Okt 2010
Antwort Antwort
Seite 1 von 2  1 2      
Blatt

Registriert seit: 8. Sep 2010
17 Beiträge
 
#1

Strings in Delphi in DLL

  Alt 21. Okt 2010, 10:08
Hi,
ich wollte in einer DLL String-Typen benutzen, aber irgendwie läuft da was schief.

Die Funktion erwartet einen PChar-Parameter und soll zur einfacheren Bearbeitung Delphi-Strings benutzen, da ich z.B. unter anderem Copy und Pos verwende.
Teilweise funktioniert das (da kann ich mir dann den einen oder anderen String ausgeben lassen) und mitten in der Funktion stürzt das Programm dann ab.
Das mit ShareMem bei String-Benutzung habe ich nicht so ganz verstanden und ich dachte, das sei auch nur notwendig, wenn man entweder einen String entgegen nimmt oder zurück gibt..
Bräuchte Hilfe..
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.624 Beiträge
 
Delphi 12 Athens
 
#2

AW: Strings in Delphi in DLL

  Alt 21. Okt 2010, 10:10
Wie wäre es denn mit etwas Quelltext (am Besten mit Markierung der Zeile, die den Fehler verursacht)?
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Blatt

Registriert seit: 8. Sep 2010
17 Beiträge
 
#3

AW: Strings in Delphi in DLL

  Alt 21. Okt 2010, 10:38
Ich habe den Code mittlerweile geändert, aber den Fehler gerade rekonstruiert:

Delphi-Quellcode:
type
  Pfoo = ^foo;
  foo = record
    other: Word;
    buf: Array of Char;
  end;

procedure test(buf: PChar);
var
  bar: Pfoo;
  lol: string;
begin
  bar := Pfoo(buf);
  lol := String(@bar.buf);
  lol := Parse(':', lol, 2);
  if Parse(' ', lol, 1) = 'hellothen
    MessageBox(0,0,0,0);
  MessageBox(0,PChar(lol), PChar(Parse(' ', lol, 1)),0);
end;
Wenn buf gleich 'x:hello' ist, erscheint die erste MessageBox nicht (die zweite zeigt 'hello' und '' im Title an), da Parse '' zurückgibt, wobei es eigentlich 'hello' sein sollte. Und wenn buf gleich 'x:hello 3' ist, stürzt das Programm ab.

Parse ist von hier:
http://www.delphipraxis.net/151836-s...r-zaehlen.html

Geändert von Blatt (21. Okt 2010 um 11:08 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.624 Beiträge
 
Delphi 12 Athens
 
#4

AW: Strings in Delphi in DLL

  Alt 21. Okt 2010, 11:15
Ich verstehe nicht ganz, wieso Du einen Record nach PChar castest. Wenn Du die Word im Record brauchst, wäre es doch IMO sinnvoll, eine Unit mit der Record-Deklaration zu erstellen und diese in der DLL und dem Programm einzubinden.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Blatt

Registriert seit: 8. Sep 2010
17 Beiträge
 
#5

AW: Strings in Delphi in DLL

  Alt 21. Okt 2010, 11:43
buf ist ein Buffer für Nachrichten über Winsock.
Ich gucke gerade, ob ich den Fehler auch in einer Standalone-Dll rekonstruieren kann.

Seltsamerweise funktioniert es gerade, wenn ich String(PChar(@bar.buf)) schreibe.
Soweit ich mich erinnere, hatte ich das davor schonmal, ohne dass es funktionierte..
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.063 Beiträge
 
Delphi 12 Athens
 
#6

AW: Strings in Delphi in DLL

  Alt 21. Okt 2010, 11:44
PS: ein Delphi-String ist auch nur ein aufgemotztes dynamisches Array ... also sollte man, bei Übergabe von dynamischen Arrays ebenfalls ShareMem einsetzen.

ShareMem sollte immer eingesetzt werden, wenn Speicher, der über den Delphi-Speichermanager läuft, über Modulgrenzen hinweg verwendet/verändert wird.

Bei diesen delphieigenen Typen, welche automatisch verwaltet werden, kann man nie genau sagen wann ein verändernder Zugriff auftreten kann, also sollte man immer ShareMem einsetzen.



Und das mit dem PChar<>Record versteh ich auch nicht,
außerdem fehlt auch noch der Zugriff auf Seite der EXE, welchen du uns vorenthältst.



Wenn Strings/DynArray nur innerhalb einer EXE oder DLL verwendet werden, aber nicht über die Modulgrenzen hinweg genutzt werden (z.B. nicht als Parameter übergeben),
dann muß ShareMem nicht verwendet werden.

ShareMem ist halt nötig, wenn Beide Resourcen (in diesem Fall den Speichermanager) gemeinsam verwenden wollen.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

Geändert von himitsu (21. Okt 2010 um 11:48 Uhr)
  Mit Zitat antworten Zitat
Blatt

Registriert seit: 8. Sep 2010
17 Beiträge
 
#7

AW: Strings in Delphi in DLL

  Alt 21. Okt 2010, 12:17
Zitat:
außerdem fehlt auch noch der Zugriff auf Seite der EXE, welchen du uns vorenthältst.
Ne, das ist einfach nur eine Nachricht über Winsock, die halt so wie das Record aussieht, zuerst ein Word, dann ein Nullterminierter String.

Ich möchte diesen String halt als Delphi-String haben. Die Adresse ist [Winsock-buf-ptr] + OffsetOf(Record-buf), deswegen -- bar := Pfoo(buf); lol := String(PChar(@bar.buf)); --


Und weil das mit den Strings nicht funktionierte, habe ich das jetzt mit PChars gemacht.
Und ein PChar zeigt bei 'hello 3' auf das '3' -- MessageBox(0,numberptr,0,0); -- funktioniert also.
Bei -- MessageBox(0,PChar(StrToInt(String(numberptr))),0, 0); -- stürzt das Programm allerdings ab..




Ich versuche gerade den Fehler in einer Standalone-Dll zu bekommen (also ohne den Client und die Winsock-Nachrichten):
Delphi-Quellcode:
procedure test(buf: PChar);
var
  bar: Pfoo;
  lol: string;
begin
  bar := Pfoo(buf);
  lol := String(PChar(@bar.buf));
  lol := Parse(':', lol, 2);
  if Parse(' ', lol, 1) = 'hellothen
    MessageBox(0,'','',0);
  MessageBox(0,PChar(lol), PChar(Parse(' ', lol, 1)),0);
end;

procedure main(reason: dword);
var
  x: Pointer;
  a: Pfoo;
  l:integer;
begin
  case reason of
    1234:
    begin
      l:=Length('');
      GetMem(x, 8);
      a := x;
      a.other := 2;
      Move('hello', a.buf, 6);

      test(PChar(x));
    end;
  end;
end;

begin
  DLLProc := @main;
  main(1234);
end.
Und da ist jetzt das Problem, dass bei -- lol := Parse(':', lol, 2); -- kein leerer String, sondern 0 zurückgegeben wird.
Deswegen kommt bei -- if S[Length(S)] <> Char then -- (aus der Parse-Funktion), aufgerufen durch -- if Parse(' ', lol, 1) = 'hello' then --, ein Fehler, da S = 0/nil ist.
Aber das ist glaub ich wieder ein anderer Fehler.....



Ist auch egal, ich beschreibe das alles viel zu schlecht, muss ich halt gucken, was ich mache
Danke für eure Hilfe!
  Mit Zitat antworten Zitat
kschit

Registriert seit: 29. Okt 2007
14 Beiträge
 
#8

AW: Strings in Delphi in DLL

  Alt 21. Okt 2010, 12:23
Also, wenn Du mit DLL's arbeitest, die an eine andere DLL übergibst und wieder was zurückbekommst solltest Du dringend FastMM oder ShareMemory verwenden. Einfach die Beispiele bei FastMM anschauen!!! Ist auch mein persönlicher Favorit!

Bei FastMM darauf achten, dass in der inc-Datei die Einstellungen für Shared DLLs eingeschalten sind!!!

Dann kannst Du auch beliebig Strings zwischen den beiden Teilen verarbeiten.

In den älteren Delphi-Versionen wird kein gutes Memory-Managment was die Arbeit mit DLL's anbelangt verwendet. Da wird ein String zwar definiert, ist dann aber nur eine Speicheradresse, die übergeben wird. Die kennt aber die DLL nicht.

Klaus
  Mit Zitat antworten Zitat
Blatt

Registriert seit: 8. Sep 2010
17 Beiträge
 
#9

AW: Strings in Delphi in DLL

  Alt 21. Okt 2010, 12:33
Ne ^^ (aber vielen Dank für die Information)
War 'ne miese Beschreibung meines Problems, sorry..
Die Dll kommt in einen Prozess und die Funktion wird nach recv aufgerufen.
Da sieht der Buffer dann halt so aus wie das Record.
Und die Nachricht, die in dem Buffer nach dem recv (Buffer sieht dann z.B. so aus: 02 00 'h' 'i' 00 | Word und String-'\0') steht, möchte ich in einem Delphi-String haben.

Geändert von Blatt (21. Okt 2010 um 12:42 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.063 Beiträge
 
Delphi 12 Athens
 
#10

AW: Strings in Delphi in DLL

  Alt 21. Okt 2010, 13:15
Man kann nicht einfach so einen Record via Socked verschicken, in welchem solche dynamische Elemente (DynArray, String, Objekt usw.) enthalten sind.

Im Record liegt von dem dynArray nur ein Zeiger, die Arraydaten verstecken sich wo anders und werden nicht mit verschickt.


Zitat:
GetMem(x, 8);
Für derartige Records reserviert man besser über Delphi-Referenz durchsuchenNew und Delphi-Referenz durchsuchenDispose den Speicher.
Nicht über GetMem/GetMemory und gibt sie erst ggarnicht über FreeMem wieder frei.

Move('hello', a.buf, 6); .
Ab Delphi 2009 tritt man mit der festen 6 in ein schönes Unicode-Fettnäpfchen.
Außerdem hast du vergessen für das dynamische Array vergessen Speicher zu reservieren > Delphi-Referenz durchsuchenSetLength.
Und das Move überschreibt hier den internen Zeiger und schreibt nicht in den Datenbereich des Arrays.


Delphi-Quellcode:
foo = record
  other: Word;
  buf: Array[0..0] of AnsiChar;
end;
- Ansi zur Vorsorge wegen eventuellem Unicode-Compiler
- über GetMem dann genügend Speicher für den gesamten Text reservieren.

Delphi-Quellcode:
Text := 'hello'; // Text = AnsiString
GetMem(a, 2{other} + Length(Text) + 1{#0}); //a := GetMemory(2{other} + Length(Text) + 1{#0});
a.other := 2;
Move(Text[1], a.buf[0], Length(Text) + 1);
Da in diesem Beispiel ein statisches Array verwendet wird, könnte man hier die [0] zwar weglassen, aber zur Sicherheit macht es sich mit [0] besser und vom Compilat her ist das Ergebnis so oder so gleich.

Geändert von himitsu (21. Okt 2010 um 13:29 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 17:55 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