Autor |
Beitrag |
Gewuerzgurke
      
Beiträge: 152
Win XP
Lazarus
|
Verfasst: Sa 12.09.09 17:15
Hallo,
hier erstmal ein Codeschnipsel:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| procedure test; var DieVariable : string; begin DieVariable := 'Normal'; ShowMessage(DieVariable); InDll(DieVariable); ShowMessage(DieVariable); FunktionPlatzhalter; FunktionPlatzhalter; FunktionPlatzhalter; end; |
Die procedure InDll steht (Wie der Name schon sagt) in einer DLL und wird dynamisch geladen:
Delphi-Quelltext 1: 2: 3: 4: 5:
| procedure InDll(out Wert : string); begin Wert := 'Geaendert'; end; exports InDll; |
Durch das out wird (Wenn ich das richtig verstanden habe) die Variable außerhalb "bearbeitet". Tatsächlich zeigt das erste ShowMessage Normal und das zweite Geaendert. Am Ende der procedure test (NACH den Platzhalter-Funktionen, die ich mal schematisch eingefügt habe) kommt aber eine Zugriffsverletzung. Ich kann in meinem Fall nicht oder nur sehr schwer mit Pointern arbeiten und komme nicht dahinter woher die Zugriffsverletzung kommt. Was kann man da machen?
|
|
HelgeLange
      
Beiträge: 735
Erhaltene Danke: 6
Windows 7
Delphi7 - Delphi XE
|
Verfasst: Sa 12.09.09 17:28
hast Du Sharemem eingebunden, wie es im Kommentar steht, den man automatisch im DPR file hat, wenn man eine neue DLL anlegt ? Sonst hast Du Probleme mit Strings von und zu DLLs
_________________ "Ich bin bekannt für meine Ironie. Aber auf den Gedanken, im Hafen von New York eine Freiheitsstatue zu errichten, wäre selbst ich nicht gekommen." - George Bernhard Shaw
|
|
Gewuerzgurke 
      
Beiträge: 152
Win XP
Lazarus
|
Verfasst: Sa 12.09.09 19:17
Hm, in meinem richtigen Programm hatte ich eigentlich keine Strings "verschickt", trotzdem kommt der Fehler jetzt nur noch beim beenden des Programms...
Das bekomme ich schon noch hin.
Vielen Dank erstmal. 
|
|
HelgeLange
      
Beiträge: 735
Erhaltene Danke: 6
Windows 7
Delphi7 - Delphi XE
|
Verfasst: So 13.09.09 01:25
Also nur mal so zum Klarstellen : Wenn Du hier Code ablieferst, der garnicht der Code ist, den Du benutzt und wir sollen da in diesem Code die Fehler suchen, die Dein anderer Code produziert, dann rechne in Zukunft nicht mehr mit meiner Hilfe  *sauer ist*
_________________ "Ich bin bekannt für meine Ironie. Aber auf den Gedanken, im Hafen von New York eine Freiheitsstatue zu errichten, wäre selbst ich nicht gekommen." - George Bernhard Shaw
|
|
Luckie
      
Beiträge: 11830
Erhaltene Danke: 162
Windows 7 Home
BDS2006
|
Verfasst: So 13.09.09 02:13
_________________ Gruß Michael
|
|
Sprint
      
Beiträge: 849
|
Verfasst: So 13.09.09 09:40
Die Verwendung von AnsiString zwischen EXE und DLL ist etwas problematisch. Da Delphi die Speicherreservierung selber vornimmt.
Also überschneiden sich EXE und DLL. Daher sollte man auch die Sharemem einsetzen. Hat den Nachteil, das du die borlndmm.dll bei
der Weitergabe mit geben musst.
Entweder du machst die Speicherreservierung selber oder du überlässt es Windows. In dem du WideString benutzt.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| library MyLib;
procedure InDll(out MyString: WideString); safecall; begin MyString := 'Geändert'; end;
exports InDll;
begin end. |
Andere Möglichkeit wäre noch über einen eigenen Speichermanager.
Ein ganz wichtiger Hinweis kam aber schon von Delphi, den du wohl übersehen hast, als du das DLL Projekt gestartet hast:
Delphi-Quelltext
_________________ Ciao, Sprint.
|
|
jaenicke
      
Beiträge: 19172
Erhaltene Danke: 1713
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: So 13.09.09 09:43
Wie er schon gesagt hat: Es ging ihm gar nicht um Strings, er hat nur irgendwas einfach so gepostet statt dem echten Quelltext...
|
|
Gewuerzgurke 
      
Beiträge: 152
Win XP
Lazarus
|
Verfasst: So 13.09.09 10:47
Der Quelltext da oben ist aus einem kleinen Testprogramm, dass ich extra zum lokalisieren des Problems geschrieben habe.
In meinem richtigen Programm wird statt einem String ein IDirect3DDevice9 (Was vermutlich auch Strings enthält) übergeben. Wenn ich da mit Pointern arbeiten würde, währe ich wieder an dem Problem, eine Variable/Funktion innerhalb einer Klasse über einen Pointer zu finden - so ähnlich wie hier: www.delphi-forum.de/viewtopic.php?t=93369 (Ja, ich arbeite immer noch an meinem Programm mit den Objekten und Records).
Mit GetProcAddress würde das vermutlich gehen aber dann ist die Performance weg.
Gut, dank Sharemem habe ich das jetzt (fast, bis auf den Fehler am Ende) gelöst.
Ich wollte den Quelltext mit IDirect3DDevice9 nicht posten, weil der groß und unüberschaubar ist - eben typisch DirectX...
[EDIT:] Oh, mein 100ster Beitrag!
|
|
HelgeLange
      
Beiträge: 735
Erhaltene Danke: 6
Windows 7
Delphi7 - Delphi XE
|
Verfasst: So 13.09.09 16:57
Falls das Direct3D zeugs zufällig aus einer Komponentensammlung kommt, dann link mal die Pakete dynamisch, ansonsten haben exe und DLL eigene Kopien und das kann zu Fehlern führen..
_________________ "Ich bin bekannt für meine Ironie. Aber auf den Gedanken, im Hafen von New York eine Freiheitsstatue zu errichten, wäre selbst ich nicht gekommen." - George Bernhard Shaw
|
|
Gewuerzgurke 
      
Beiträge: 152
Win XP
Lazarus
|
Verfasst: Mo 14.09.09 17:15
Wie meinst du das "Exe und Dll haben eigene Kopien"? Heist das, ich muss die DLLs für DirectX auch dynamisch laden?
Der Fehler am Programmende kommt übrigens von ShareMem. Auch wenn ich die DLLs weglasse und nur ShareMem einbinde kommt am Ende ein Fehler  . Außerdem habe ich gelesen, dass man mit ShareMem immer eine ShareMem.dll mitgeben muss, kann diese aber nirgendwo finden.
Sharemem soll außerdem sehr langsam sein - was in meinem Fall ärgerlich währe. Ich habe schon überlegt, etwas anderes statt ShareMem zu verwenden, was die Sache aber nicht unerheblich verkomplizieren würde...
Wie groß ist denn der Performance-Verlust von ShareMem?
Außerdem verstehe ich nicht, warum die Strings überhaupt problematisch sind, wenn ich out verwende...
|
|
Sprint
      
Beiträge: 849
|
Verfasst: Mo 14.09.09 20:10
Gewuerzgurke hat folgendes geschrieben : | Der Fehler am Programmende kommt übrigens von ShareMem. Auch wenn ich die DLLs weglasse und nur ShareMem einbinde kommt am Ende ein Fehler |
Hast du ShareMem als erste Unit in der DPR eingetragen?
Zitat: | Außerdem habe ich gelesen, dass man mit ShareMem immer eine ShareMem.dll mitgeben muss, kann diese aber nirgendwo finden. |
borlndmm.dll
Zitat: | Ich habe schon überlegt, etwas anderes statt ShareMem zu verwenden, was die Sache aber nicht unerheblich verkomplizieren würde... |
Es gibt ja einige Alternativen. Selber würde ich ShareMem auch nicht nutzen.
Zitat: | Außerdem verstehe ich nicht, warum die Strings überhaupt problematisch sind, wenn ich out verwende... |
Weil deine EXE und deine DLL einen MemoryManager haben. Also in einem Programm zwei. Beide versuchen dann den AnsiString zu verwalten.
Wo es dann zu Problemen kommen kann. Bei WideString übernimmt Windows die Verwaltung.
Und bei der Nutzung von ShareMem bzw. deren Alternativen übernehmen die dann die Speicherverwaltung.
Darum muss die Unit auch an erster Stelle in deiner DPR stehen.
Moderiert von Narses: Überflüssige Zeilenumbrüche/Leerzeilen entfernt.
Moderiert von Sprint: Benötigte Zeilenumbrüche/Leerzeilen hinzugefügt.
_________________ Ciao, Sprint.
Zuletzt bearbeitet von Sprint am Di 15.09.09 13:40, insgesamt 1-mal bearbeitet
|
|
Gewuerzgurke 
      
Beiträge: 152
Win XP
Lazarus
|
Verfasst: Mo 14.09.09 21:12
Ich hatte es als zweites eingetragen... Zu blöd aber auch. Jetzt, wo (<-- Umgangssprache  ) ich es überall als erstes eingetragen habe, geht's.
Die borlndmm.dll habe ich im Bin von Delphi gefunden - muss ich die jetzt immer im gleichen Ordner wie mein Programm mitgeben, wenn das andere System kein Delphi hat?
|
|
jaenicke
      
Beiträge: 19172
Erhaltene Danke: 1713
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mo 14.09.09 21:47
|
|
Gewuerzgurke 
      
Beiträge: 152
Win XP
Lazarus
|
Verfasst: Mo 14.09.09 22:27
Och nö! Das zerstört mir das ganze Panorama
Wenn ich die DLL in einen Unterordner schieben wollte, müsste ich vermutlich die ShareMem.pas anpassen - und die ist nur als .dcu vorhanden und vermutlich urheberrechtlich geschützt...
Ich glaub' ich versuch's doch mal mit den Alternativen.
|
|
Gewuerzgurke 
      
Beiträge: 152
Win XP
Lazarus
|
Verfasst: Do 17.09.09 22:41
Jetzt muss ich doch noch mal fragen, ob es nicht eine Möglichkeit gibt, die DLL doch in einen Unterordner zu schieben. Ich muss ja für DirectX sowieso schon welche mitliefern.
Ich meine in Delphi liegt sie ja auch in einem anderen Ordner. Stellt man so was über die Registy ein?
|
|
jaenicke
      
Beiträge: 19172
Erhaltene Danke: 1713
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 18.09.09 02:35
Die DLL muss von Windows gefunden werden, also im PATH liegen. Die kann auch in ein Unterverzeichnis gelegt werden, wenn dieses dem PATH hinzugefügt wird oder theoretisch auch ins System32-Verzeichnis gelegt werden (wobei bei letzterem eine Warnung notwendig wäre, dass ggf. andere Programme beeinträchtigt werden durch dein Programm). Beides hat aber einige Nachteile. Zum Beispiel, dass man das Programm nicht mehr einfach in ein anderes Verzeichnis schieben kann bzw. dass man ggf. Versionskonflikte mit den DLLs bekommt.
Deshalb würde ich das lieber in das Verzeichnis der Exe legen (wie es Microsoft auch empfiehlt) statt da zusätzliche Verrenkungen machen zu müssen. Möglich ist es natürlich auch wie oben gesagt, vorausgesetzt du benutzt ein Setup.
|
|
Gewuerzgurke 
      
Beiträge: 152
Win XP
Lazarus
|
Verfasst: Fr 18.09.09 14:44
Achso. Naja, dann sind halt da ein Paar DLLs mit im Verzeichnis. Ich kann sie ja noch verstecken, dann sollte es nicht weiter stören.
|
|