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 immer noch Stress mit DLL Aufruf (https://www.delphipraxis.net/37921-immer-noch-stress-mit-dll-aufruf.html)

alf.stefan 12. Jan 2005 10:50


immer noch Stress mit DLL Aufruf
 
Das Problem von mir im vorigen Thread
Zitat:

habe DLL aber nur C++ und VB Beispiele
ist behoben ich bin aber immer noch nicht glücklich.

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:
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;
wenn ich folgende Zeile weglasse oder auskommentiere funtioniert alles aufs Beste
Code:
.......
      ........
      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;
   ........
   ........
was ist da los?? Muß ich die ganzen Pointer die ich hier generiert habe aufräumen oder löschen?
Hat da jemand eine Idee?

Ratloser Gruß

Stefan

alf.stefan 12. Jan 2005 13:12

Re: immer noch Stress mit DLL Aufruf
 
immer noch nicht weitergekommen

im CPU Fenster hängt das Programm mit der Access Violation

bei
Code:
     
@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
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!

Ich hoffe mir kann noch jemand helfen.

Gruß
Stefan

Die Muhkuh 12. Jan 2005 13:18

Re: immer noch Stress mit DLL Aufruf
 
Zitat:

Zitat von alf.stefan
Delphi-Quellcode:
.......
      ........
      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;
   ........
   ........

Hi,

vielleicht fehlen da die @?

Ich kenn mich mit so Zeugs zwar nicht aus, aber ein Versuch ist das immer wert.

alf.stefan 12. Jan 2005 13:27

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:
[Fehler] Unit1.pas(100): Inkompatible Typen: 'String' und 'Pointer'
trotzdem Danke

Gruß

Stefan

Christian Seehase 12. Jan 2005 13:51

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?

alf.stefan 12. Jan 2005 14:04

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

Christian Seehase 12. Jan 2005 14:24

Re: immer noch Stress mit DLL Aufruf
 
Moin Stefan,

was mir gerade erst auffällt:
Delphi-Quellcode:
name[c] := new(pChar);
funktioniert sowieso nicht. Es muss heissen:
Delphi-Quellcode:
new(name[c]);
Ich möchte lieber nicht wissen, was das Programm da beim Ablauf macht ;-)

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:
 for c:= 0 to MAX_TCP_NM_LENGTH do name[c] := new(pChar);
Du verwendest hinterher ja eh' nur das Element[0].
Dann könntest Du ja auf das Ganze verzichten, und gleich
Delphi-Quellcode:
New(nBuff[lLoop]);
schreiben.

Jetzt, wo ich noch einmal einen Blick da reinwerfe:
Die Schleife könnte auch so aussehen:
Delphi-Quellcode:
for lLoop := 0 to NumDevices-1 do begin
  nBuff[lLoop] := AllocMem(MAX_TCP_NM_LENGTH+1);
  // usw.
end;
Danach ein try und im finally dann die Schleife erneut, allerdings mit FreeMem.

Robert Marquardt 12. Jan 2005 14:45

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;

alf.stefan 12. Jan 2005 16:00

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

Robert Marquardt 13. Jan 2005 05:32

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 07:03 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