AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Pointer vom String übergeben und ändern
Thema durchsuchen
Ansicht
Themen-Optionen

Pointer vom String übergeben und ändern

Ein Thema von TheMiller · begonnen am 16. Mär 2007 · letzter Beitrag vom 17. Mär 2007
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von TheMiller
TheMiller

Registriert seit: 19. Mai 2003
Ort: Gründau
2.480 Beiträge
 
Delphi XE7 Architect
 
#1

Pointer vom String übergeben und ändern

  Alt 16. Mär 2007, 17:40
Hallo,

hab ein kleines Problem mit einem Pointer. Verwende sie öfter aber an der einen Stelle knallt's ab und zu (unregelmäßig). Ich veruche vom Hauptprogramm an eine DLL eine Adresse von einem String zu übergeben, diesen in einer Variable zu speichern und dann als Rückgabewert wieder ins Programm einzuschleusen:

Delphi-Quellcode:
Hauptprogramm:

var
s: String;
begin
  s:=Hallo;
  dllprozedur(@s);
end;


DLL

function dllprozedure(s: PString): String; stdcall;
var
  localS: String:
begin
  localS:=s^;
  localS:=localS+'sdsd';
  return:=localS;
end;
Wie gesagt. Ab und zu gehts, ab und zu kommt die Meldung

Zugriffverletzung bei Adresse 0164F144. Lesen von Adresse 0164F144

Wenn ich das Programm neustarte, gehts wieder...
  Mit Zitat antworten Zitat
Benutzerbild von inherited
inherited

Registriert seit: 19. Dez 2005
Ort: Rosdorf
2.022 Beiträge
 
Turbo Delphi für Win32
 
#2

Re: Pointer vom String übergeben und ändern

  Alt 16. Mär 2007, 18:05
Benutzt du den Borland Memory-Manager?
Was ist reutrn? Gibt s das tatsächlich? Ist mir zumindest neu. ich benutze immer result, alasse mich aber gerne belehren
Hast du schonmal daran gedacht, eventuell PChars zu benutzen, statt Strings? Dann könntest du auf die aufgebläht borlndmm.dll verzichten.
Nikolai Wyderka

SWIM SWIM HUNGRY!
Neuer Blog: hier!
  Mit Zitat antworten Zitat
Benutzerbild von TheMiller
TheMiller

Registriert seit: 19. Mai 2003
Ort: Gründau
2.480 Beiträge
 
Delphi XE7 Architect
 
#3

Re: Pointer vom String übergeben und ändern

  Alt 16. Mär 2007, 18:08
Hi,

ich habe mich geirrt. Return heißt es in PHP - verwechsle das gerne. Den MemoryManager benutze ich nicht. Allerdings passiert das auch bei PChars... Ein PChar ist ja auch nur ein Pointer...
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

Re: Pointer vom String übergeben und ändern

  Alt 16. Mär 2007, 19:52
@DJ-SPM: doch tust du


Der DelphiMemoryManager / BorlandMM (wird standardmäßig in Delphiprogrammen verwendet) erstellt für jedes Moul eine eigenstänfdige Instanz, welche nur ihren eigenen Speicher verwalten kann.

Es wird also jeweils für die EXE und die DLL ein eigener MemoryManager verwendet.

Der Speicher für die Strings wird beim lokalen MemoryManager reserviert.

Demnach ist es nicht möglich einen String von einem Modul an ein Anderes zu übergeben.

Denn wenn der MM versucht den Speicher eines Strings auf 'nem anerem Modul zu veränder/freizugeben, dann kracht es halt, da der Speicherblock wo der String drin ist ja dem anderem MM gehört.


Fazit: sowas ist nicht möglich.


Lösung: ein alternativer Shared-MemoryManager wie z.B. FastMM.

FastMM kann sich ProgrammGlobal initialisieren, also nur einmal für alle Module welchen ihn verwenden.


Oder du holst dir den Speicherblock direkt von Windows, oder sorgs dafür daß der Speicherblock nicht Modulübergreifend verändert wird.




Delphi-Quellcode:
var s: String[255]; < Wichtig: keine dynamischen Strings
begin
  s:=Hallo;
  dllprozedur(@s);
end;


procedure dllprozedure(var s: String[255]);
begin
  S:=S+'sdsd';
end;

PS: WideString ist derzeit (ich hoffe das ändert sich bald endlich mal) keine delphieigene Struktur.
Bei Diesem wird intern alles, was das Speichermanagement angeht, auf einen OLE-String umgeleitet und demnach von der ole32.dll verwaltet.
Da es die ole32.dll nur einmal im Programm gibt wird demnach ebenfalls die gesamte Verwaltung nur von dieser DLL übernommen und ist somit auch ohne einen alternativen MemoryManager Modulübergreifend (die ole32.dll hat sozusagen ihren eigenen MM eingebaut)
$2B or not $2B
  Mit Zitat antworten Zitat
Benutzerbild von TheMiller
TheMiller

Registriert seit: 19. Mai 2003
Ort: Gründau
2.480 Beiträge
 
Delphi XE7 Architect
 
#5

Re: Pointer vom String übergeben und ändern

  Alt 16. Mär 2007, 20:01
Ja, so mache ich es doch. Mir ist aufgefallen, (und so habe ich es jetzt auch gelöst, dass wenn ich die DLLs immer wieder freigebe wenn ich sie nicht brauche und dann wieder lade, wenn ich sie brauche, alles funktioniert. Ist zwar eine seltsame Lösung, aber das klappt.

Was mich irritiert ist, dass ich mehrere DLLs habe, mit denen ich auf gleiche Art und Weise die Strings übergebe und es da nie Probleme gab. Immer nur mit der einen DLL. Da scheint der Wurm / Bug drin zu sein. Ansosnten habe ich es ja richtig gemacht... Die String sind die Länger als 255 Zeichen, obwohl das auch geht. Habe ich schon probiert.

Oder irre ich mich da?
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

Re: Pointer vom String übergeben und ändern

  Alt 16. Mär 2007, 20:12
Es kommt auf den Sringinhalt an.

z.B.

Delphi-Quellcode:
// Pointer(S) = nil
S := '';

// Pointer(S) = ziegt direkt auf den Datenbereich, wo '1234' im Programmcode gespeichert ist
S := '1234';

// Pointer(S) = Pointer(S2) ... wobei hier nur der Referenzzähler geändert wird
S := S2;

// neuer String wird resserviert und die gesamten Stringdaten werden da reinkopiert
// die alten Stringdaten werden freigegeben
S := S + '12';

S := S2;
UniqueString(S);
// das Selbe wie bei S := S2;
// nur daß hier noch die Stringdaten nachträglich in einen eigenen Datenbereich
// kopiert und natürlich der Refferenzzähler wieder zurückgesetzt wird

...
Du siehst daß nicht immer Daten im Speicher/RAM liegen, oder gar an der Speicherverwaltung was geändert wird.

Demnach kann es auch mal keine Probleme geben.

Probleme tauchen nur auf wo die Speicherverwaltung, also hier speziell BorlandMM ins Spiel kommt.



Also es ist ganz einfach ... solange man getrenne Speichermanager verwendet sollta man nicht an den speicherverwaltung veränderntes über Modulgrenzen hinweg machen.

Aber wenn man weiß was intern wirklich passiert, dann kann man eventuelleinige "eigenarten" ausnutzen.
z.B. geht sowas, da hierbei der MM nicht ins Spiel kommt.
Delphi-Quellcode:
procedure dllprozedure(const s: String);
var s2: string;
begin
  s2 := s;
  UniqueString(s2);
  // Ab hier kann dan mit S2 alles gemacht werden, was man
  // will, egal von wo S an diese Prozedur übergeben wurde.
  // Selbst über die Grenzen der Prozedur hinaus ... solange
  // der String innerhalb des Moduls (EXE/DLL) verbleibt.
  ...
  
end;


function dllprozedure(const s: string): string;
begin
  if s = '123then
    result := 'irgendwas'
  else
  if s = '456then
    result := 'nochwas'
  else
    result := 'keinen plan';
end;
$2B or not $2B
  Mit Zitat antworten Zitat
Benutzerbild von TheMiller
TheMiller

Registriert seit: 19. Mai 2003
Ort: Gründau
2.480 Beiträge
 
Delphi XE7 Architect
 
#7

Re: Pointer vom String übergeben und ändern

  Alt 16. Mär 2007, 20:18
Ja, die Erfahrung musste ich halt machen - da bin ich mit Sicherheit auch nicht der eingige *g*. Nur schon seltsam, dass ein neuladen der DLL dieses Problem wieder behebt. Selbst wenn ich die Pointer mit s:=nil freigebe, funktioniert es nicht ohne entladen und erneutes laden der DLL.

ACHSO: ShareMem ist nicht eingebunden - nirgends.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

Re: Pointer vom String übergeben und ändern

  Alt 16. Mär 2007, 20:28
hab oben noch was nachgetragen ^^

wie entlädst du die DLLs?
und du bist dir sicher, daß du dir keine speicherlecks einhandelst?

und solltest du besser mal, jedenfalls wenn du sowas machst (ShareMem, oder vergleichbares)
schließlich merkst du ja die Probleme ohne diesen.
$2B or not $2B
  Mit Zitat antworten Zitat
Benutzerbild von TheMiller
TheMiller

Registriert seit: 19. Mai 2003
Ort: Gründau
2.480 Beiträge
 
Delphi XE7 Architect
 
#9

Re: Pointer vom String übergeben und ändern

  Alt 16. Mär 2007, 21:43
Das Beispiel schaue ich mir nochmal an - also das, was du oben nachgetragen hast.

Ich entlade die DLLs mit FreeLibrary (habe sie dynamsich geladen und die Handles gespeichert). Und ich habe sogar FastMM4 eingebunden wleches mir in KEINEM meiner Module Speicherlecks anzeigt. Habe immer alles brav beseitigt. Wie gesagt, ich verstehe es selbst nicht.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

Re: Pointer vom String übergeben und ändern

  Alt 16. Mär 2007, 21:54
Hast du FastMM auch auf SharedMemory umgestellt?
(in der entsprechenden .inc)

Wenn ich mich recht erinnere ist dieses ja per Standard deaktiviert.
$2B or not $2B
  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 03:47 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