fann delphi binding - probleme mit pointern

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
laz78
Beiträge: 9
Registriert: Mi 26. Apr 2017, 21:44

fann delphi binding - probleme mit pointern

Beitrag von laz78 »

sorry das ich so viele fragen stelle aber ich habe sie gesammelt, es sind die punkte an denen ich allein nicht weiterkomme :roll: einige von euch kennen ja evtl FANN http://leenissen.dk/, für FANN existiert ein etwas älteres delphi binding http://leenissen.dk/fann/wp/language-bindings/ (FANN V 2.1). dieses hab ich mir in eine dll gepackt, läuft auch alles und funktioniert einwandfrei.

jetzt bräuchte ich zugriff auf bereits geladene trainingsdaten und steck fest.

Code: Alles auswählen

unit FANN; // << nur auszüge also die wichtigen zeilen
 
{$MODE Delphi}
 
const DLL_FILE = 'fanndouble.dll'
 
type
 
  fann_type = double;
 
  /////////////////////////////////////////////////
 
  Fann_Type_Array   = Array [0..65535] of fann_type; 
  PFann_Type_Array  = ^Fann_Type_Array; 
  PPFann_Type_Array = Array [0..65535] of ^Fann_Type_Array;
 
 /////////////////////////////////////////////////
 
  TFann_Train_Data = packed record // liegts evtl an dem packed und den pointern ? ich counte unten i++
    errno_f: cardinal;
    erro_log: PFile;
    errstr: PChar; 
    num_data: cardinal;
    num_input: cardinal;
    num_ouput: cardinal; 
    input : PPFann_Type_Array;
    output: PPFann_Type_Array; 
  end;
 
.........................
 


Code: Alles auswählen

unit meine_dll; // << nur auszüge also die wichtigen zeilen
 
{$MODE Delphi}
 
type
 
 /////////////////////////////////////////////////
 PFann_Train_Data = ^TFann_Train_Data;
 /////////////////////////////////////////////////
 FNetwork = record
  trn_ptr : PFann_Train_Data; // pointer to train data struct
 end;
 /////////////////////////////////////////////////
 
var
 ANN : Array of FNetwork;


Code: Alles auswählen

hlp_log(fnc + ' | _aid ' + IntToStr(_aid) + ' | low_input ' + IntToStr(Low(ANN[_aid].trn_ptr.input)))
hlp_log(fnc + ' | _aid ' + IntToStr(_aid) + ' | hgh_input ' + IntToStr(High(ANN[_aid].trn_ptr.input)))
hlp_log(fnc + ' | --------------------------------------------------------------')
hlp_log(fnc + ' | _aid ' + IntToStr(_aid) + ' | low_input[0] ' + IntToStr(Low(ANN[_aid].trn_ptr.input[0]^)))
hlp_log(fnc + ' | _aid ' + IntToStr(_aid) + ' | hgh_input[0] ' + IntToStr(High(ANN[_aid].trn_ptr.input[0]^)))
hlp_log(fnc + ' | --------------------------------------------------------------');

ergibt

Code: Alles auswählen

28.04.2017 16:26:36 | pca_create() | --------------------------------------------------------------
28.04.2017 16:26:36 | pca_create() | _aid 0 | low_input 0
28.04.2017 16:26:36 | pca_create() | _aid 0 | hgh_input 65535
28.04.2017 16:26:36 | pca_create() | --------------------------------------------------------------
28.04.2017 16:26:36 | pca_create() | _aid 0 | low_input[0] 0
28.04.2017 16:26:36 | pca_create() | _aid 0 | hgh_input[0] 65535
 

wenn ich versuche durch das 2d array zu steppen krieg ich ab input[( j > 1)][i] eine access violation im dll-host. (i) hab ich schon bis 1000 getestet, das geht.

Code: Alles auswählen

28.04.2017 16:12:54 | pca_create() | --------------------------------------------------------------
28.04.2017 16:12:55 | pca_create() | j 0 | i 0 | input[0][0] 3,6729E-262
28.04.2017 16:12:55 | pca_create() | j 0 | i 1 | input[0][1] 3,6748E-262
28.04.2017 16:12:55 | pca_create() | j 1 | i 0 | input[1][0] 1,1302E-266
28.04.2017 16:12:55 | pca_create() | j 1 | i 1 | input[1][1] 1,1302E-266 
 

ich habe die trainingsdaten structur mal komplett in ein file gespeichert, sie sind also vorhanden und sie stimmen.

Code: Alles auswählen

FloatToStr(ANN[_aid].trn_ptr^.input[j]^[i])

es liegt also an meinem zugriff, was stimmt hier nicht?

lieben dank :wink:
Zuletzt geändert von laz78 am Sa 29. Apr 2017, 04:52, insgesamt 14-mal geändert.

Mathias
Beiträge: 6193
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: fann delphi binding - probleme mit pointern

Beitrag von Mathias »

Mal eine Frage, brauchst du zwingend so grosse statische Arrays ?
Evtl. kannst du dein Problem mit dynamischen Arrays lösen, so ein Pointer-Salat würde ich meiden, wen es irgenwie geht.

Wen man mit Pointern arbeitet, sind Fehler vorprogrammiert. Der kleinste Fehler und man muss suchen wie gestört.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

laz78
Beiträge: 9
Registriert: Mi 26. Apr 2017, 21:44

Re: fann delphi binding - probleme mit pointern

Beitrag von laz78 »

hi mathias, ich stimme dir in den punkten teilweise zu, pointer haben aber auch vorteile ;) allerdings ist das oben (FANN.pas) der original quellcode aus dem FANN delphi binding, also nicht mein code. die structur TFann_Train_Data enthält die im delphi binding verwendete structur für die trainingsdaten, kann also hier nichts ändern weil es sich global auswirken würde.

edit - - - ich habs (glaube ich) gefunden....

er erstellt in dem delphi binding (FANN.pas) nur die identische structur der TFann_Train_Data um einen gültigen pointer erstellen zu können. das heisst die arrays dienen zur bereitsstellung der nötigen pointeradressen, der speicherplatz wird aber nie reserviert. berichtigt mich ruhig, ich sage nur wie ich es mir denke. habe mal getestet was passiert wenn ich mir den inhalt mal direkt nach dem erhalt lade:

Code: Alles auswählen

 /////////////////////////////////////////////////
 
 ANN[_aid].trn_ptr := fann_read_train_from_file(@_ptr); // fann_read_train_from_file() liegt in der fanndouble.dll die in meiner dll geladen wird => anderer speicherbereich?
 
 /////////////////////////////////////////////////
 
 hlp_log(fnc + ' | _aid ' + IntToStr(_aid) + ' | ' + IntToStr(res) + ' loading pointer');
 
 /////////////////////////////////////////////////
 
 ANN[_aid].trn_dat := ANN[_aid].trn_ptr^; // access violation jetzt bereits hier 
 

ergo ich hab kein zugriff auf diesen speicherbereich???
warum nicht? die fanndouble.dll die den pointer erstellt wird innerhalb meiner dll geladen ?


ich kann aber wenn ich nicht zugreife durch das 2d array counten? versteh ich nicht :shock:

Code: Alles auswählen

for j := Low(ANN[_aid].trn_ptr^.input)     to High(ANN[_aid].trn_ptr^.input)     do
 
for i := Low(ANN[_aid].trn_ptr^.input[j]^) to High(ANN[_aid].trn_ptr^.input[j]^) do begin
---------------------
29.04.2017 04:38:22 | pca_create() | j 3 | i 3 | input[3][3] : 2,95495385366047E-314
29.04.2017 04:38:22 | pca_create() | j 3 | i 4 | input[3][4] : 2,95495385366047E-314
29.04.2017 04:38:22 | pca_create() | j 3 | i 5 | input[3][5] : 2,95495385366047E-314
29.04.2017 04:38:22 | pca_create() | j 4 | i 0 | input[4][0] : 2,95495385366047E-314
29.04.2017 04:38:22 | pca_create() | j 4 | i 1 | input[4][1] : 2,95495385366047E-314

gucken ABER nicht anfassen ? :D :roll:

liegt es daran, dass der pointer innerhalb der fanndouble.dll erstellt wird und deswegen habe ich keinen zugriff oder habe ich hier nen denkfehler? fallen euch andere wege ein, wie ich an die daten kommen könnte? evtl. mit ReadProcessMemory() - https://msdn.microsoft.com/de-de/library/windows/desktop/ms680553(v=vs.85).aspx?

super ab FANN 2.3 gibts dafür ne funktion, leider ist meine fanndouble.dll nur v2.1 :evil: https://libfann.github.io/fann/docs/files/fann_train-h.html#fann_get_train_input

Antworten