![]() |
immer noch Stress mit DLL Aufruf
Das Problem von mir im vorigen Thread
Zitat:
Wenn ich auf die von der DLL Funktion zurückgelieferten Werte zugreife bekomme ich eine ACCESS VIOLATION und dann geht gar nix mehr. Das heißt es funktioniert alles wunderbar und die erwünschten Strings werden von der Funktion zurückgeliefert und im Memo1 Appended, aber nach verlassen der event routine und erst dann kommt die Access violation- siehe code
Code:
wenn ich folgende Zeile weglasse oder auskommentiere funtioniert alles aufs Beste
procedure TForm1.Button1Click(Sender: TObject);
var lLoop,c : word; err, getNum : KMErrorCode; NumDevices : Word; erg : string; nBuff,ipBuff,SerStrBuff : array of Pchar; DipArrayBuff : Array of PUint16; name : Array[0..MAX_TCP_NM_LENGTH] of pChar; ip: Array[0..MAX_TCP_IP_LENGTH] of pChar; ser: Array[0..MAX_TCP_SN_LENGTH] of pChar; sName, sIp, sSerial : String; begin err := KMInitialize; Memo1.Lines.Append('Wait....'); NumDevices :=0; KMTCPRefreshDevices(); getNum := KMTCPGetNumDevices(NumDevices); SetLength(nBuff, NumDevices); SetLength(ipBuff, NumDevices); SetLength(serStrBuff, NumDevices); SetLength(DipArrayBuff, NumDevices); for lLoop := 0 to NumDevices-1 do begin for c:= 0 to MAX_TCP_NM_LENGTH do name[c] := new(pChar); nBuff[lLoop] := name[0]; for c:= 0 to MAX_TCP_IP_LENGTH do ip[c] := new(pChar); ipBuff[lLoop] := ip[0]; for c:= 0 to MAX_TCP_SN_LENGTH do ser[c] := new(pChar); serStrBuff[lLoop] := ser[0]; DipArrayBuff[lLoop] := new(PUint16); end; if getNum = 0 then begin err := KMTCPGetDeviceInformation(@nBuff[0], @ipBuff[0], @serStrBuff[0], DipArrayBuff[0], NumDevices); end; if err = 0 then begin memo1.Lines.Append(' Controllers Found '+IntToStr(NumDevices)); for c:= 0 to NumDevices-1 do begin Memo1.Lines.Append('Name : '+nBuff[c]); Memo1.Lines.Append('Ip-Addr : '+ipBuff[c]); Memo1.Lines.Append('Serial : '+serStrBuff[c]); Memo1.Lines.Append('Dip Settings : '+IntToStr(DipArrayBuff[c]^)); Memo1.Lines.Append(StringOfChar('-', 60)); end; end; Memo1.Lines.Append('finished'); end;
Code:
was ist da los?? Muß ich die ganzen Pointer die ich hier generiert habe aufräumen oder löschen?
.......
........ memo1.Lines.Append(' Controllers Found '+IntToStr(NumDevices)); for c:= 0 to NumDevices-1 do begin Memo1.Lines.Append('Name : '+nBuff[c]); Memo1.Lines.Append('Ip-Addr : '+ipBuff[c]); Memo1.Lines.Append('Serial : '+serStrBuff[c]); Memo1.Lines.Append('Dip Settings : '+IntToStr(DipArrayBuff[c]^)); Memo1.Lines.Append(StringOfChar('-', 60)); end; end; ........ ........ Hat da jemand eine Idee? Ratloser Gruß Stefan |
Re: immer noch Stress mit DLL Aufruf
immer noch nicht weitergekommen
im CPU Fenster hängt das Programm mit der Access Violation bei
Code:
kann da jemand Rückschlüss daraus ziehen was da falsch läuft! Welche StringArrays muß ich da löschen oder freigeben oder was auch immer!@LStrArrayClear: 00404240 53 push ebx 00404241 56 push esi .... .... 0040424A 7414 jz +$1a 0040424C C7030000000 mov [ebx], $00000000 00404252 8B4AF8 mov ecx,[edx-$08] und da steht der programm zeiger Ich hoffe mir kann noch jemand helfen. Gruß Stefan |
Re: immer noch Stress mit DLL Aufruf
Zitat:
vielleicht fehlen da die @? Ich kenn mich mit so Zeugs zwar nicht aus, aber ein Versuch ist das immer wert. |
Re: immer noch Stress mit DLL Aufruf
Die Ausgabe in das Memo funktioniert perfekt.
Der Absturz ist - HinterHer!!! Wenn die Funktion schon verlassen ist. Von daher brauche ich das mit dem Address Operator nicht auszuprobieren weil es der Compiler schon gar nicht akzeptiert.
Code:
trotzdem Danke
[Fehler] Unit1.pas(100): Inkompatible Typen: 'String' und 'Pointer'
Gruß Stefan |
Re: immer noch Stress mit DLL Aufruf
Moin Stefan,
was mir so als erstes auffällt: Wo gibst Du denn Deine ganzen mit New erzeugten Variablen wieder frei? |
Re: immer noch Stress mit DLL Aufruf
Hallo Christian
gute Frage bis jetzt überhaupt nicht. Habs vorhin mal versucht, aber da hat das Programm seine Zeiger total durcheinender gebracht und dann hab ich es gelassen. Glaubst Du es kann sein, daß wenn ich die Rückgabewerte nicht verwende, daß die dann vom Compiler rausoptimiert werden und es deshalb funktioniert solange ich auf diese Daten nicht zugreife? Kannst Du mir vielleicht einen Tip geben wie ich die new(pChar) wieder freigeben kann, ohne daß sich das Programm seine Zeiger verbiegt??? Danke schonmal Hoffnungsvoller Gruß Stefan |
Re: immer noch Stress mit DLL Aufruf
Moin Stefan,
was mir gerade erst auffällt:
Delphi-Quellcode:
funktioniert sowieso nicht. Es muss heissen:
name[c] := new(pChar);
Delphi-Quellcode:
Ich möchte lieber nicht wissen, was das Programm da beim Ablauf macht ;-)
new(name[c]);
Schau Dir noch mal genau die Doku zu New an. Ausserdem scheint die Struktur noch einmal überarbeitungswürdig ;-) Der Code dürfte Speicherlücken ohne Ende produzieren, selbst wenn Du das Erzeugen der Variablen umkehrst, um sie freizugeben. Name, ip usw. sind ja nur eindimensionale Arrays (abgesehen davon, dass der Bezeichner Name unglücklich gewählt ist, da das Formular auch eine Eigenschaft dieses Namens hat), du belegst dieses aber für jeden Durchlauf von lLoop mit neuen Werten. Am Ende kommst Du also nur noch an die Daten von [NumDevices-1] sowie alle [0] heran. Was dazwischenliegt, kann nicht mehr freigegeben werden, da Du keinen Zugriff mehr darauf hast. Durch die Struktur steige ich auch nicht ganz durch. Wozu diese Schleifen:
Delphi-Quellcode:
Du verwendest hinterher ja eh' nur das Element[0].
for c:= 0 to MAX_TCP_NM_LENGTH do name[c] := new(pChar);
Dann könntest Du ja auf das Ganze verzichten, und gleich
Delphi-Quellcode:
schreiben.
New(nBuff[lLoop]);
Jetzt, wo ich noch einmal einen Blick da reinwerfe: Die Schleife könnte auch so aussehen:
Delphi-Quellcode:
Danach ein try und im finally dann die Schleife erneut, allerdings mit FreeMem.
for lLoop := 0 to NumDevices-1 do begin
nBuff[lLoop] := AllocMem(MAX_TCP_NM_LENGTH+1); // usw. end; |
Re: immer noch Stress mit DLL Aufruf
Koenntest du vielleicht wie vorgeschlagen deine Funktion entmisten?
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var err, getNum : KMErrorCode; NumDevices : Word; c : Integer; name : array [0..MAX_TCP_NM_LENGTH] of PChar; ip: array [0..MAX_TCP_IP_LENGTH] of PChar; ser: array [0..MAX_TCP_SN_LENGTH] of PChar; dip: array [0..MAX_TCP_SN_LENGTH] of Word; begin err := KMInitialize; Memo1.Lines.Append('Wait....'); NumDevices := 0; KMTCPRefreshDevices(); getNum := KMTCPGetNumDevices(NumDevices); if getNum = 0 then err := KMTCPGetDeviceInformation(@name[0], @ip[0], @ser[0], dip[0], NumDevices); if err = 0 then begin memo1.Lines.Append(' Controllers Found ' + IntToStr(NumDevices)); for I := 0 to NumDevices - 1 do begin Memo1.Lines.Append('Name : ' + name[I]); Memo1.Lines.Append('Ip-Addr : ' + ip[I]); Memo1.Lines.Append('Serial : ' + ser[I]); Memo1.Lines.Append('Dip Settings : ' + IntToStr(dip[I])); Memo1.Lines.Append(StringOfChar('-', 60)); end; end; Memo1.Lines.Append('finished'); end; |
Re: immer noch Stress mit DLL Aufruf
Hallo Robert, Hallo Christian
Ihr habt ja recht. Aber ich versuche mich zu bessern. Und ich werde morgen früh gleich als erstes eure Vorschläge (sofern sie sich vereinbaren lassen) umsetzen. Versprochen. Bis dahin Beschämter Gruß Stefan |
Re: immer noch Stress mit DLL Aufruf
Einer von den Vorschlaegen sollte helfen.
Meiner geht davon aus das die Funktion PChar's abliefert, die auf interne Zeichenketten weisen. Alternativ koennte die Funktion auch erwarten das die PChar's auf Puffer weisen, in die kopiert wird. Das sollte aber die Doku verraten. Wahrscheinlicher ist die erste Version. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:23 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz