Italian community of Lazarus and Free Pascal

Programmazione => Generale => Topic aperto da: Simon75 - Maggio 03, 2013, 12:05:41 pm

Titolo: DLL Profilabexpert
Inserito da: Simon75 - Maggio 03, 2013, 12:05:41 pm
Ciao a tutti, ho bisogno ancora di un vostro aiuto su come caricare nel display il file txt.
Attualmente grazie a Nomore.. Stilgar e Legolas sono riuscito a salvare su disco senza il numero 5 modificando L'array.
Ora ho difficoltà a caricare nel display il file txt e Profilab mi genera un errore (Violazione di accesso).

Vi ringrazio

Codice: [Seleziona]



library project1;

{$mode objfpc}{$H+}

uses
  Interfaces,
  Classes,
  SysUtils,
  Windows,
  FileUtil,
  Forms,
  Controls,
  Graphics,
  Dialogs,
  ShellApi;

const
  Inputs = 3;  // quantita entrata
  Outputs = 1; // quantita uscita

  {INPUTS}// nome per numero di entrata
  I0 = 0;  // valore I0 = PInput[I0] ossia PInput[0]
  I1 = 1;  // valore I1 = PInput[I1] ossia PInput[1]
  Leggi = 2;
  // I3 = 3;
  // ... I99 = 99;

  {OUTPUTS}// nome per numero di uscita
  Stampa = 0;  // valore Q0 = POutput[Q0] ossia POutput[0]
  //Q1 = 1;  // valore Q1 = POutput[Q1] ossia POutput[1]

  // Q3 = 3;
  // ... Q99 = 99;

  {USER}// nome per numero di variabile, I valori vengono memorizzati

  U0 = 0; // valore U0 = PUser[U0] ossia PUser[0]
  // U1 = 1;
  // U2 = 2;
  // U3 = 3;
  // ... U99 = 99;

  // I0,I1,I2,I3,Q0,Q1,Q2,Q3,U0,U1,U2,U3
  // I nomi possono essere qualsiasi, sono case-insensitive
var
  globalDialog: TFileDialog;

type

  TDLLParams = array[0..100] of extended; //Type of ProfiLab DLL parameters
  PDLLParams = ^TDLLParams;               // Pointer to ProfiLab DLL parameters

  TStringParams = array[0..100] of PChar;   //Type of ProfiLab DLL parameters
  PStringParams = ^TStringParams;        // Pointer to ProfiLab DLL parameters


  function ApriSaveDialog: ShortString;

  begin
    Result := '';
    if not assigned(globalDialog) then
    begin
      globalDialog := TSaveDialog.Create(nil);
      try
        globalDialog.DefaultExt := 'txt';

        globalDialog.Filter := '*.txt';
        if globalDialog.Execute then
          Result := globalDialog.FileName
        else
          Result := '';
      finally
        FreeAndNil(globalDialog);
      end;
    end;
  end;




  function ApriOpenDialog: ShortString;
  begin
    Result := '';
    if not assigned(globalDialog) then
    begin
      globalDialog := TOpenDialog.Create(nil);
      try
        globalDialog.DefaultExt := 'txt';
        globalDialog.Filter := '*.txt';
        if globalDialog.Execute then
          Result := globalDialog.FileName
        else
          Result := '';
      finally
        FreeAndNil(globalDialog);
      end;
    end;
  end;

  function NumInputs: byte;
  begin
    Result := Inputs; // trasferire quantita entrata
  end;

  function NumOutputs: byte;
  begin
    Result := Outputs; // trasferire quantita uscita
  end;

  function InputName(Channel: byte): ShortString; // trasferire nome di entrata
  begin
    case Channel of
      I0: Result := 'I0'; // nome di pin I0
      I1: Result := 'I1'; // nome di pin I1
      Leggi: Result := '$Leggi';
    end;
  end;

  function OutputName(Channel: byte): ShortString; // trasferire nome di uscita
  begin
    case Channel of
      Stampa: Result := '$Stampa'; // nome di pin Q0
      //Q1: Result := 'Q1'; // nome di pin Q1
    end;
  end;


  procedure SimStart(PInput, POutput, PUser: PDLLParams);
  // Routine viene eseguita solo al primo avvio
  begin

  end;


  procedure SalvaArrayInFile(FileName: string; PAParams: PDLLParams);
  var
    i: integer;
    sl: TStringList;
  begin

    sl := TStringList.Create;
    try
      for i := 2 to 3 do
        // for i := low(PAParams^) to high(PAParams^) do

        if PAParams^[i] <> 0 then


          sl.Add(FloatToStr(PAParams^[i]));


      sl.SaveToFile(FileName);
    finally
      sl.Free;
    end;

  end;

  procedure CaricaArrayDaFile(FileName: string; PAParams: PDLLParams);
  var
    i: integer;
    sl: TStringList;
    e: extended;
    s: string;
  begin

    sl := TStringList.Create;
    try
      sl.LoadFromFile(FileName);

        for i := low(PAParams^) to high(PAParams^) do

      begin

        s := sl.Values[IntToStr(i)];
        e := StrToFloat(s);
        PAParams^[i] := e;

      end;
    finally

      sl.Free;
    end;

  end;

  procedure CalculateEx(PInput, POutput, PUser: PDLLParams; PStrings: PStringParams);
  // Routine è permanente
  var
    sl: TStringList;
    s: string;
  begin
    if PInput^[I0] > 2.5 then
    begin
      if (PInput^[I0] > 2.5) and not (PUser^[U0] > 2.5) then
      begin
        s := ApriOpenDialog;
        if s <> '' then
          CaricaArrayDaFile(s, POutput);
      end;
    end;
    PUser^[U0] := PInput^[I0];

    if PInput^[I1] > 2.5 then
    begin
      if (PInput^[I1] > 2.5) and not (PUser^[I1] > 2.5) then
      begin
        s := ApriSaveDialog;
        if s <> '' then
          SalvaArrayInFile(s, PInput);
      end;
    end;
    PUser^[I1] := PInput^[I1];
  end;




  procedure SimStop(PInput, POutput, PUser: PDLLParams);
  // Routine viene eseguita solo in fase di chiusura
  begin

  end;


  //export methods for ProfiLab
exports
  SimStart,
  SimStop,
  NumInputs,
  NumOutputs,
  CalculateEx,
  InputName,
  OutputName,
  ApriOpenDialog,
  ApriSaveDialog;
begin
end.         
Titolo: Re:DLL Profilabexpert
Inserito da: nomorelogic - Maggio 05, 2013, 11:30:28 am
immagino che la funzione incriminata sia:
CaricaArrayDaFile

se si, dov'è che ti da l'access violation?
Titolo: Re:DLL Profilabexpert
Inserito da: Simon75 - Maggio 06, 2013, 10:13:35 am
Si è CaricaArrayDaFile, ma sembra non  funzioni proprio, l'errore esce quando premo Apri sulla finestra di dialogo.

Titolo: Re:DLL Profilabexpert
Inserito da: nomorelogic - Maggio 06, 2013, 01:23:53 pm
Si è CaricaArrayDaFile, ma sembra non  funzioni proprio, l'errore esce quando premo Apri sulla finestra di dialogo.

ho dato un'occhiata e potrebbe non essere così
il tutto dovrebbe partire da CalculateEx, questa a sua volta richiama ApriOpenDialog e successivamente CaricaArrayDaFile
se l'errore ti compare prima dell'OpenDialog, l'errore deve essere qua:

Codice: [Seleziona]
procedure CalculateEx(PInput, POutput, PUser: PDLLParams; PStrings: PStringParams);
  // Routine è permanente
  var
    sl: TStringList;
    s: string;
  begin
    if PInput^[I0] > 2.5 then
    begin
      if (PInput^[I0] > 2.5) and not (PUser^[U0] > 2.5) then
      begin
        s := ApriOpenDialog;

si tratta di un accesso in memoria non valido e quindi dovresti controllare:
PInput^[I0]
PUser^[U0]
ApriOpenDialog

che ci siano valori validi nei puntatori
Titolo: Re:DLL Profilabexpert
Inserito da: Stilgar - Maggio 06, 2013, 05:33:49 pm
PInput, POutput e PUser sono allocati? Quanti elementi hanno?

Apri della finestra di dialogo ... c'è un file selezionato? Ovvero il componente restituisce veramente una stringa piena?
Mettere un file di log per tracciare cosa fa la dll non sarebbe un'idea barbina.

per create il file (vado a memoria):

Codice: [Seleziona]
  assignFile(Ouput, 'dll.txt.dove finisce il log');
  rewrite (Output);


per scrivere dentro il file, a questo punto, basta usare l'ustruzione "write".

Almeno puoi avere qualche info aggiuntiva nell'analisi dei problemi.

Stilgar
Titolo: Re:DLL Profilabexpert
Inserito da: Simon75 - Maggio 07, 2013, 02:46:49 pm
L'errore mi esce da qs punto, quando premo apri

dentro il file txt ci sono solo numeri

(http://imageshack.us/a/img201/161/20130507135914.png)
Titolo: Re:DLL Profilabexpert
Inserito da: Stilgar - Maggio 08, 2013, 09:37:08 am
L'errore che esce?
Titolo: Re:DLL Profilabexpert
Inserito da: Stilgar - Maggio 08, 2013, 09:54:34 am
Codice: [Seleziona]

procedure log(msg :String);
begin
AssignFile(Output, 'Debug.txt');
if (FileExists('Debug.txt')) then
begin
Append(Output);
end
else
begin
Rewrite(Output);
end;
WriteLn(Output, msg);
Flush(Output);
CloseFile(Output);
end;

Ciao, usa questo pezzo di codice per verificare cosa succede, scrivendo le cosine su file ;)

Stilgar
Titolo: Re:DLL Profilabexpert
Inserito da: Simon75 - Maggio 08, 2013, 10:02:51 pm
Mi esce qs errore :

(http://i44.tinypic.com/5l72vr.png)

Violazione di accesso......


l'ho inserita dopo  CaricaArrayDaFile ma non capisco cosa dovrebbe fare, o meglio come si usa

Codice: [Seleziona]

  procedure CaricaArrayDaFile(FileName: string; PAParams: PDLLParams);
  var
    i: integer;
    sl: TStringList;
    e: extended;
    s: string;
  begin

    sl := TStringList.Create;
    try
      sl.LoadFromFile(FileName);
      //for  i := 1 to 6 do
      for i := low(PAParams^) to high(PAParams^) do

      begin

        s := sl.Values[IntToStr(i)];
        e := StrToFloat(s);
        PAParams^[i] := e;

      end;
    finally

      sl.Free;
    end;

  end;

procedure log(msg: string);
begin
  AssignFile(Output, 'Debug.txt');
  if (FileExists('Debug.txt')) then
  begin
    Append(Output);
  end
  else
  begin
    Rewrite(Output);
  end;
  WriteLn(Output, msg);
  Flush(Output);
  CloseFile(Output);
end;
Titolo: Re:DLL Profilabexpert
Inserito da: Stilgar - Maggio 08, 2013, 10:56:48 pm
mmmm inizio ad avere qualche idea ...

Codice: [Seleziona]
procedure log(msg: string);
begin
  AssignFile(Output, 'Debug.txt');
  if (FileExists('Debug.txt')) then
  begin
    Append(Output);
  end
  else
  begin
    Rewrite(Output);
  end;
  WriteLn(Output, msg);
  Flush(Output);
  CloseFile(Output);
end;

procedure CalculateEx(PInput, POutput, PUser: PDLLParams; PStrings: PStringParams);   // Routine è permanente
var
  sl: TStringList;
  s:  string;
begin
  if PInput^[I0] > 2.5 then
  begin
    if (PInput^[I0] > 2.5) and not (PUser^[U0] > 2.5) then
    begin
      s := ApriOpenDialog;
      log('Nome del file selezionato : ' + s);
      if s <> '' then
      begin
        if assigned(POutput) then
          log('POutput ok')
        else
          raise Exception.Create('Non ci siamo');

        CaricaArrayDaFile(s, POutput);
      end;
    end;
  end;
  PUser^[U0] := PInput^[I0];
  if PInput^[I1] > 2.5 then
  begin
    if (PInput^[I1] > 2.5) and not (PUser^[I1] > 2.5) then
    begin
      s := ApriSaveDialog;
      if s <> '' then
        SalvaArrayInFile(s, PInput);
    end;
  end;
  PUser^[I1] := PInput^[I1];
end;

procedure CaricaArrayDaFile(FileName: string; PAParams: PDLLParams);
var
  i:  integer;
  sl: TStringList;
  e:  extended;
  s:  string;
begin
  sl := TStringList.Create;
  try
    try
      sl.LoadFromFile(FileName);
      for i := low(PAParams^) to high(PAParams^) do
      begin
        s := sl.Values[IntToStr(i)];
        e := StrToFloat(s);
        PAParams^[i] := e;
      end;

    except
      on e: Exception do
      begin
        log('porca miseria! "' + e.message + '"');
        raise e;
      end;
    end;
  finally
    sl.Free;
  end;
end;

   
Titolo: Re:DLL Profilabexpert
Inserito da: Simon75 - Maggio 10, 2013, 01:44:00 pm
Allora ho provato e nel file Debug.txt mi è uscito questo:


Nome del file selezionato : C:\Documents and Settings\Simone\Desktop\dll\Prova.txt
POutput ok
porca miseria! """ is an invalid float"

Codice: [Seleziona]



library project1;

{$mode objfpc}{$H+}

uses
  Interfaces,
  Classes,
  SysUtils,
  Windows,
  FileUtil,
  Forms,
  Controls,
  Graphics,
  Dialogs,
  ShellApi;

const
  Inputs = 3;  // quantita entrata
  Outputs = 1; // quantita uscita

  {INPUTS}// nome per numero di entrata
  I0 = 0;  // valore I0 = PInput[I0] ossia PInput[0]
  I1 = 1;  // valore I1 = PInput[I1] ossia PInput[1]
  Leggi = 2;
  // I3 = 3;
  // ... I99 = 99;

  {OUTPUTS}// nome per numero di uscita
  Stampa = 0;  // valore Q0 = POutput[Q0] ossia POutput[0]
  //Q1 = 1;  // valore Q1 = POutput[Q1] ossia POutput[1]

  // Q3 = 3;
  // ... Q99 = 99;

  {USER}// nome per numero di variabile, I valori vengono memorizzati

  U0 = 0; // valore U0 = PUser[U0] ossia PUser[0]
  // U1 = 1;
  // U2 = 2;
  // U3 = 3;
  // ... U99 = 99;

  // I0,I1,I2,I3,Q0,Q1,Q2,Q3,U0,U1,U2,U3
  // I nomi possono essere qualsiasi, sono case-insensitive
var
  globalDialog: TFileDialog;

type

  TDLLParams = array[0..100] of extended; //Type of ProfiLab DLL parameters
  PDLLParams = ^TDLLParams;               // Pointer to ProfiLab DLL parameters

  TStringParams = array[0..100] of PChar;   //Type of ProfiLab DLL parameters
  PStringParams = ^TStringParams;        // Pointer to ProfiLab DLL parameters


  function ApriSaveDialog: ShortString;

  begin
    Result := '';
    if not assigned(globalDialog) then
    begin
      globalDialog := TSaveDialog.Create(nil);
      try
        globalDialog.DefaultExt := 'txt';

        globalDialog.Filter := '*.txt';
        if globalDialog.Execute then
          Result := globalDialog.FileName
        else
          Result := '';
      finally
        FreeAndNil(globalDialog);
      end;
    end;
  end;




  function ApriOpenDialog: ShortString;
  begin
    Result := '';
    if not assigned(globalDialog) then
    begin
      globalDialog := TOpenDialog.Create(nil);
      try
        globalDialog.DefaultExt := 'txt';
        globalDialog.Filter := '*.txt';
        if globalDialog.Execute then
          Result := globalDialog.FileName
        else
          Result := '';
      finally
        FreeAndNil(globalDialog);
      end;
    end;
  end;

  function NumInputs: byte;
  begin
    Result := Inputs; // trasferire quantita entrata
  end;

  function NumOutputs: byte;
  begin
    Result := Outputs; // trasferire quantita uscita
  end;

  function InputName(Channel: byte): ShortString; // trasferire nome di entrata
  begin
    case Channel of
      I0: Result := 'I0'; // nome di pin I0
      I1: Result := 'I1'; // nome di pin I1
      Leggi: Result := '$Leggi';
    end;
  end;

  function OutputName(Channel: byte): ShortString; // trasferire nome di uscita
  begin
    case Channel of
      Stampa: Result := '$Stampa'; // nome di pin Q0
      //Q1: Result := 'Q1'; // nome di pin Q1
    end;
  end;




  procedure SimStart(PInput, POutput, PUser: PDLLParams);
  // Routine viene eseguita solo al primo avvio
  begin

  end;



  procedure SalvaArrayInFile(FileName: string; PAParams: PDLLParams);
  var
    i: integer;
    sl: TStringList;
  begin

    sl := TStringList.Create;
    try
      for i := 2 to 3 do
        // for i := low(PAParams^) to high(PAParams^) do

        if PAParams^[i] <> 0 then


          sl.Add(FloatToStr(PAParams^[i]));


      sl.SaveToFile(FileName);
    finally
      sl.Free;
    end;

  end;

  procedure log(msg: string);
  begin
    AssignFile(Output, 'Debug.txt');
    if (FileExists('Debug.txt')) then
    begin
      Append(Output);
    end
    else
    begin
      Rewrite(Output);
    end;
    WriteLn(Output, msg);
    Flush(Output);
    CloseFile(Output);
  end;

  procedure CaricaArrayDaFile(FileName: string; PAParams: PDLLParams);
  var
    i: integer;
    sl: TStringList;
    e: extended;
    s: string;
  begin
    sl := TStringList.Create;
    try
      try
        sl.LoadFromFile(FileName);
        for i := low(PAParams^) to high(PAParams^) do
        begin
          s := sl.Values[IntToStr(i)];
          e := StrToFloat(s);
          PAParams^[i] := e;
        end;

      except
        on e: Exception do
        begin
          log('porca miseria! "' + e.message + '"');
          raise e;
        end;
      end;
    finally
      sl.Free;
    end;
  end;

  procedure CalculateEx(PInput, POutput, PUser: PDLLParams; PStrings: PStringParams);
  // Routine è permanente
  var
    sl: TStringList;
    s: string;
  begin
    if PInput^[I0] > 2.5 then
    begin
      if (PInput^[I0] > 2.5) and not (PUser^[U0] > 2.5) then
      begin
        s := ApriOpenDialog;
        log('Nome del file selezionato : ' + s);
        if s <> '' then
        begin
          if assigned(POutput) then
            log('POutput ok')
          else
            raise Exception.Create('Non ci siamo');

          CaricaArrayDaFile(s, POutput);
        end;
      end;
    end;
    PUser^[U0] := PInput^[I0];
    if PInput^[I1] > 2.5 then
    begin
      if (PInput^[I1] > 2.5) and not (PUser^[I1] > 2.5) then
      begin
        s := ApriSaveDialog;
        if s <> '' then
          SalvaArrayInFile(s, PInput);
      end;
    end;
    PUser^[I1] := PInput^[I1];
  end;




  procedure SimStop(PInput, POutput, PUser: PDLLParams);
  // Routine viene eseguita solo in fase di chiusura
  begin

  end;


  //export methods for ProfiLab
exports
  SimStart,
  SimStop,
  NumInputs,
  NumOutputs,
  CalculateEx,
  InputName,
  OutputName,
  ApriOpenDialog,
  ApriSaveDialog;
begin
end.   



Titolo: Re:DLL Profilabexpert
Inserito da: Stilgar - Maggio 10, 2013, 02:20:32 pm
E l'errore cosa ti dice?
Che il valore che stai leggendo non gli piace.... ;) Il potere dei log sui file :D
Titolo: Re:DLL Profilabexpert
Inserito da: Simon75 - Maggio 10, 2013, 02:49:25 pm
Si...
ma dici che è un problema di tipo di dato? oppure non accetta il file.txt?
Titolo: Re:DLL Profilabexpert
Inserito da: Stilgar - Maggio 10, 2013, 02:56:49 pm
Stai convertendo una stringa vuota...

"" is an invalid float

Quindi ... o stai leggendo "porcheria" o stai facendo delle assunzioni che il codice non rispetta.
1) Controlla il file dati.
2) Verifica che sia veramente caricato il contenuto che ti aspetti.

il ciclo di lettura delle stringhe lo modificherei in:
Codice: [Seleziona]
 for i := low(PAParams^) to high(PAParams^) do
        begin
          s := sl.Values[IntToStr(i)];
        if s <> '' then
begin
          e := StrToFloat(s);
          PAParams^[i] := e;
end
else
begin
  log(IntToStr(i)+' non caricato');
end
        end;

Titolo: Re:DLL Profilabexpert
Inserito da: Simon75 - Maggio 10, 2013, 04:09:20 pm
Ho provato  modificare come mi hai indicato e l'errore non esce più ma non carica niente nel dispaly.

Forse l'array è sbagliato?

E nel Debug.txt mi esce questo:

Nome del file selezionato : C:\Documents and Settings\Simone\Desktop\dll\Prova.txt
POutput ok
0 non caricato
1 non caricato
2 non caricato
3 non caricato
4 non caricato
5 non caricato
6 non caricato
7 non caricato
8 non caricato
9 non caricato
10 non caricato
11 non caricato
12 non caricato
13 non caricato
14 non caricato
15 non caricato
16 non caricato
17 non caricato
18 non caricato
19 non caricato
20 non caricato
21 non caricato
22 non caricato
23 non caricato
24 non caricato
25 non caricato
26 non caricato
27 non caricato
28 non caricato
29 non caricato
30 non caricato
31 non caricato
32 non caricato
33 non caricato
34 non caricato
35 non caricato
36 non caricato
37 non caricato
38 non caricato
39 non caricato
40 non caricato
41 non caricato
42 non caricato
43 non caricato
44 non caricato
45 non caricato
46 non caricato
47 non caricato
48 non caricato
49 non caricato
50 non caricato
51 non caricato
52 non caricato
53 non caricato
54 non caricato
55 non caricato
56 non caricato
57 non caricato
58 non caricato
59 non caricato
60 non caricato
61 non caricato
62 non caricato
63 non caricato
64 non caricato
65 non caricato
66 non caricato
67 non caricato
68 non caricato
69 non caricato
70 non caricato
71 non caricato
72 non caricato
73 non caricato
74 non caricato
75 non caricato
76 non caricato
77 non caricato
78 non caricato
79 non caricato
80 non caricato
81 non caricato
82 non caricato
83 non caricato
84 non caricato
85 non caricato
86 non caricato
87 non caricato
88 non caricato
89 non caricato
90 non caricato
91 non caricato
92 non caricato
93 non caricato
94 non caricato
95 non caricato
96 non caricato
97 non caricato
98 non caricato
99 non caricato
100 non caricato



   


 
 

             
               
Prova a verificare quanto ho fatto:

Codice: [Seleziona]




library project1;

{$mode objfpc}{$H+}

uses
  Interfaces,
  Classes,
  SysUtils,
  Windows,
  FileUtil,
  Forms,
  Controls,
  Graphics,
  Dialogs,
  ShellApi;

const
  Inputs = 3;  // quantita entrata
  Outputs = 1; // quantita uscita

  {INPUTS}// nome per numero di entrata
  I0 = 0;  // valore I0 = PInput[I0] ossia PInput[0]
  I1 = 1;  // valore I1 = PInput[I1] ossia PInput[1]
  Leggi = 2;
  // I3 = 3;
  // ... I99 = 99;

  {OUTPUTS}// nome per numero di uscita
  Stampa = 0;  // valore Q0 = POutput[Q0] ossia POutput[0]
  //Q1 = 1;  // valore Q1 = POutput[Q1] ossia POutput[1]

  // Q3 = 3;
  // ... Q99 = 99;

  {USER}// nome per numero di variabile, I valori vengono memorizzati

  U0 = 0; // valore U0 = PUser[U0] ossia PUser[0]
  // U1 = 1;
  // U2 = 2;
  // U3 = 3;
  // ... U99 = 99;

  // I0,I1,I2,I3,Q0,Q1,Q2,Q3,U0,U1,U2,U3
  // I nomi possono essere qualsiasi, sono case-insensitive
var
  globalDialog: TFileDialog;

type

  TDLLParams = array[0..100] of extended; //Type of ProfiLab DLL parameters
  PDLLParams = ^TDLLParams;               // Pointer to ProfiLab DLL parameters

  TStringParams = array[0..100] of PChar;   //Type of ProfiLab DLL parameters
  PStringParams = ^TStringParams;        // Pointer to ProfiLab DLL parameters


  function ApriSaveDialog: ShortString;

  begin
    Result := '';
    if not assigned(globalDialog) then
    begin
      globalDialog := TSaveDialog.Create(nil);
      try
        globalDialog.DefaultExt := 'txt';

        globalDialog.Filter := '*.txt';
        if globalDialog.Execute then
          Result := globalDialog.FileName
        else
          Result := '';
      finally
        FreeAndNil(globalDialog);
      end;
    end;
  end;




  function ApriOpenDialog: ShortString;
  begin
    Result := '';
    if not assigned(globalDialog) then
    begin
      globalDialog := TOpenDialog.Create(nil);
      try
        globalDialog.DefaultExt := 'txt';
        globalDialog.Filter := '*.txt';
        if globalDialog.Execute then
          Result := globalDialog.FileName
        else
          Result := '';
      finally
        FreeAndNil(globalDialog);
      end;
    end;
  end;

  function NumInputs: byte;
  begin
    Result := Inputs; // trasferire quantita entrata
  end;

  function NumOutputs: byte;
  begin
    Result := Outputs; // trasferire quantita uscita
  end;

  function InputName(Channel: byte): ShortString; // trasferire nome di entrata
  begin
    case Channel of
      I0: Result := 'I0'; // nome di pin I0
      I1: Result := 'I1'; // nome di pin I1
      Leggi: Result := '$Leggi';
    end;
  end;

  function OutputName(Channel: byte): ShortString; // trasferire nome di uscita
  begin
    case Channel of
      Stampa: Result := '$Stampa'; // nome di pin Q0
      //Q1: Result := 'Q1'; // nome di pin Q1
    end;
  end;




  procedure SimStart(PInput, POutput, PUser: PDLLParams);
  // Routine viene eseguita solo al primo avvio
  begin

  end;



  procedure SalvaArrayInFile(FileName: string; PAParams: PDLLParams);
  var
    i: integer;
    sl: TStringList;
  begin

    sl := TStringList.Create;
    try
      for i := 2 to 3 do
        // for i := low(PAParams^) to high(PAParams^) do

        if PAParams^[i] <> 0 then


          sl.Add(FloatToStr(PAParams^[i]));


      sl.SaveToFile(FileName);
    finally
      sl.Free;
    end;

  end;

  procedure log(msg: string);
  begin
    AssignFile(Output, 'Debug.txt');
    if (FileExists('Debug.txt')) then
    begin
      Append(Output);
    end
    else
    begin
      Rewrite(Output);
    end;
    WriteLn(Output, msg);
    Flush(Output);
    CloseFile(Output);
  end;

  procedure CaricaArrayDaFile(FileName: string; PAParams: PDLLParams);
  var
    i: integer;
    sl: TStringList;
    e: extended;
    s: string;
  begin
    sl := TStringList.Create;
    try
      try
        sl.LoadFromFile(FileName);
        for i := low(PAParams^) to high(PAParams^) do
        begin
          s := sl.Values[IntToStr(i)];
          if s <> '' then
          begin
            e := StrToFloat(s);
            PAParams^[i] := e;
          end
          else
          begin
            log(IntToStr(i) + ' non caricato');
          end;
        end;


      except
        on e: Exception do
        begin
          log('porca miseria! "' + e.message + '"');
          raise e;
        end;
      end;
    finally
      sl.Free;
    end;
  end;

  procedure CalculateEx(PInput, POutput, PUser: PDLLParams; PStrings: PStringParams);
  // Routine è permanente
  var
    sl: TStringList;
    s: string;
  begin
    if PInput^[I0] > 2.5 then
    begin
      if (PInput^[I0] > 2.5) and not (PUser^[U0] > 2.5) then
      begin
        s := ApriOpenDialog;
        log('Nome del file selezionato : ' + s);
        if s <> '' then
        begin
          if assigned(POutput) then
            log('POutput ok')
          else
            raise Exception.Create('Non ci siamo');

          CaricaArrayDaFile(s, POutput);
        end;
      end;
    end;
    PUser^[U0] := PInput^[I0];
    if PInput^[I1] > 2.5 then
    begin
      if (PInput^[I1] > 2.5) and not (PUser^[I1] > 2.5) then
      begin
        s := ApriSaveDialog;
        if s <> '' then
          SalvaArrayInFile(s, PInput);
      end;
    end;
    PUser^[I1] := PInput^[I1];
  end;




  procedure SimStop(PInput, POutput, PUser: PDLLParams);
  // Routine viene eseguita solo in fase di chiusura
  begin

  end;


  //export methods for ProfiLab
exports
  SimStart,
  SimStop,
  NumInputs,
  NumOutputs,
  CalculateEx,
  InputName,
  OutputName,
  ApriOpenDialog,
  ApriSaveDialog;
begin
end.
Titolo: Re:DLL Profilabexpert
Inserito da: Stilgar - Maggio 10, 2013, 04:49:54 pm
Codice: [Seleziona]
s := sl.Values[IntToStr(i)];
prova a cambiarlo in
Codice: [Seleziona]
s := sl[I];
.
Messo così ci possono essere errori, controlla che "I" sia un indice valido.
Titolo: Re:DLL Profilabexpert
Inserito da: Simon75 - Maggio 15, 2013, 04:41:37 pm
Niente Stilgar  non riesco a caricare niente nel display.
la log mi indica sempre (non caricato).

anche inserendo
Codice: [Seleziona]
s := sl[I];






Titolo: Re:DLL Profilabexpert
Inserito da: Stilgar - Maggio 15, 2013, 05:03:03 pm
Ok, ma il file è popolato? Sembrerà una domanda scema, ma a volte sono proprio le cose più banali che dimentichiamo di controllare.
Titolo: Re:DLL Profilabexpert
Inserito da: nomorelogic - Maggio 15, 2013, 06:14:51 pm
non trova nessun valore valido: o, come dice Stilgar, non è popolato il file o nelle righe non c'è una stringa nulla ma qualcos'altro
prova ad usare questo codice e vediamo cosa esce nel log

Codice: [Seleziona]
for i := low(PAParams^) to high(PAParams^) do
    begin
       s := sl.Values[IntToStr(i)];
       log(IntToStr(i)+': valore = <' + s + '>');
       if s <> '' then begin
          e := StrToFloat(s);
          PAParams^[i] := e;
          log('   + IntToStr(i)+' caricato');
       end else begin
          log('  ' + IntToStr(i)+' non caricato');
       end;
    end;

Titolo: Re:DLL Profilabexpert
Inserito da: Simon75 - Maggio 15, 2013, 10:03:19 pm
ho notato che quando rimane premuto il tasto carica ovvero ( I0 = 0  )nel display si vede il valore 5

il codice l'ho inserito qui:

Codice: [Seleziona]


  procedure CaricaArrayDaFile(FileName: string; PAParams: PDLLParams);
  var
    i: integer;
    sl: TStringList;
    e: extended;
    s: string;
  begin
    sl := TStringList.Create;
    try
      try
        sl.LoadFromFile(FileName);
        for i := low(PAParams^) to high(PAParams^) do
        begin
          s := sl.Values[IntToStr(i)];
          log(IntToStr(i) + ': valore = <' + s + '>');
          if s <> '' then
          begin
            e := StrToFloat(s);
            PAParams^[i] := e;
            log('   ' + IntToStr(i) + ' caricato');
          end
          else
          begin
            log('  ' + IntToStr(i) + ' non caricato');
          end;
        end;
  except
        on e: Exception do
        begin
          log('porca miseria! "' + e.message + '"');
          raise e;
        end;
      end;
    finally
      sl.Free;
    end;
  end;     

Mi tira fuori questo:

Nome del file selezionato : C:\Users\Simone75\Desktop\Dado\dll\Prova.txt
POutput ok
0: valore = <>
  0 non caricato
1: valore = <>
  1 non caricato
2: valore = <>
  2 non caricato
3: valore = <>
  3 non caricato
4: valore = <>
  4 non caricato
5: valore = <>
  5 non caricato
6: valore = <>
  6 non caricato
7: valore = <>
  7 non caricato
8: valore = <>
  8 non caricato
9: valore = <>
  9 non caricato
10: valore = <>
  10 non caricato
11: valore = <>
  11 non caricato
12: valore = <>
  12 non caricato
13: valore = <>
  13 non caricato
14: valore = <>
  14 non caricato
15: valore = <>
  15 non caricato
16: valore = <>
  16 non caricato
17: valore = <>
  17 non caricato
18: valore = <>
  18 non caricato
19: valore = <>
  19 non caricato
20: valore = <>
  20 non caricato
21: valore = <>
  21 non caricato
22: valore = <>
  22 non caricato
23: valore = <>
  23 non caricato
24: valore = <>
  24 non caricato
25: valore = <>
  25 non caricato
26: valore = <>
  26 non caricato
27: valore = <>
  27 non caricato
28: valore = <>
  28 non caricato
29: valore = <>
  29 non caricato
30: valore = <>
  30 non caricato
31: valore = <>
  31 non caricato
32: valore = <>
  32 non caricato
33: valore = <>
  33 non caricato
34: valore = <>
  34 non caricato
35: valore = <>
  35 non caricato
36: valore = <>
  36 non caricato
37: valore = <>
  37 non caricato
38: valore = <>
  38 non caricato
39: valore = <>
  39 non caricato
40: valore = <>
  40 non caricato
41: valore = <>
  41 non caricato
42: valore = <>
  42 non caricato
43: valore = <>
  43 non caricato
44: valore = <>
  44 non caricato
45: valore = <>
  45 non caricato
46: valore = <>
  46 non caricato
47: valore = <>
  47 non caricato
48: valore = <>
  48 non caricato
49: valore = <>
  49 non caricato
50: valore = <>
  50 non caricato
51: valore = <>
  51 non caricato
52: valore = <>
  52 non caricato
53: valore = <>
  53 non caricato
54: valore = <>
  54 non caricato
55: valore = <>
  55 non caricato
56: valore = <>
  56 non caricato
57: valore = <>
  57 non caricato
58: valore = <>
  58 non caricato
59: valore = <>
  59 non caricato
60: valore = <>
  60 non caricato
61: valore = <>
  61 non caricato
62: valore = <>
  62 non caricato
63: valore = <>
  63 non caricato
64: valore = <>
  64 non caricato
65: valore = <>
  65 non caricato
66: valore = <>
  66 non caricato
67: valore = <>
  67 non caricato
68: valore = <>
  68 non caricato
69: valore = <>
  69 non caricato
70: valore = <>
  70 non caricato
71: valore = <>
  71 non caricato
72: valore = <>
  72 non caricato
73: valore = <>
  73 non caricato
74: valore = <>
  74 non caricato
75: valore = <>
  75 non caricato
76: valore = <>
  76 non caricato
77: valore = <>
  77 non caricato
78: valore = <>
  78 non caricato
79: valore = <>
  79 non caricato
80: valore = <>
  80 non caricato
81: valore = <>
  81 non caricato
82: valore = <>
  82 non caricato
83: valore = <>
  83 non caricato
84: valore = <>
  84 non caricato
85: valore = <>
  85 non caricato
86: valore = <>
  86 non caricato
87: valore = <>
  87 non caricato
88: valore = <>
  88 non caricato
89: valore = <>
  89 non caricato
90: valore = <>
  90 non caricato
91: valore = <>
  91 non caricato
92: valore = <>
  92 non caricato
93: valore = <>
  93 non caricato
94: valore = <>
  94 non caricato
95: valore = <>
  95 non caricato
96: valore = <>
  96 non caricato
97: valore = <>
  97 non caricato
98: valore = <>
  98 non caricato
99: valore = <>
  99 non caricato
100: valore = <>
  100 non caricato
Titolo: Re:DLL Profilabexpert
Inserito da: Stilgar - Maggio 16, 2013, 12:31:38 am
Ma il file ... cosa contiene?
Non lo hai ancora postato.
Titolo: Re:DLL Profilabexpert
Inserito da: nomorelogic - Maggio 16, 2013, 03:08:29 pm
dal log sembrerebbe contenere un centinaio di "accapo" e basta
Titolo: Re:DLL Profilabexpert
Inserito da: Simon75 - Maggio 16, 2013, 05:21:58 pm
Questo è quello che tento di caricare


(http://i43.tinypic.com/669t01.png)
Titolo: Re:DLL Profilabexpert
Inserito da: Stilgar - Maggio 16, 2013, 09:12:35 pm
ok, allora prova a non usare values[] ma direttamente [].
Stai caricando tutta la stringa, non devi farla interpretare....
Se metti 45=0,1
Forse alla posizione 45 ti trova 0,1
Ma non ci giurerei così su 2 piedi ;)
Stilgar
Titolo: Re:DLL Profilabexpert
Inserito da: Simon75 - Maggio 17, 2013, 09:12:10 am
Ma dici in questa riga?

Codice: [Seleziona]
s := sl.Values[IntToStr(i)];



Ho provato  a salvare con il ; usandolo come separatore es: 34;56  il programma mi salva solo il 34 il 56 non lo vede.
Devo indicare il tipo di dato giusto?
Titolo: Re:DLL Profilabexpert
Inserito da: nomorelogic - Maggio 17, 2013, 09:33:24 am
Ma dici in questa riga?

Codice: [Seleziona]
s := sl.Values[IntToStr(i)];

si prova a sostituirla con:
Codice: [Seleziona]
 s := sl[i];


Edit:
i numeri vanno salvati con la notazione anglosassone, quindi il separatore decimale è il punto "." e non la virgola ","
se non puoi usare il punto, devi aggirare la cosa con FormatSettings
Titolo: Re:DLL Profilabexpert
Inserito da: Simon75 - Maggio 17, 2013, 11:00:55 am
Inserendo questo:

Codice: [Seleziona]

 s := sl[i];



La  Log mi tira fuori:


Nome del file selezionato : C:\Documents and Settings\Simone\Desktop\dll\Prova.txt
POutput ok
0: valore = <45>
  0 caricato
porca miseria! "List index (1) out of bounds"
Titolo: Re:DLL Profilabexpert
Inserito da: Stilgar - Maggio 17, 2013, 11:28:18 am
Non controlli gli indici e la validità dei limiti .
Ve bene fare il ciclo for per l'array in memeoria, ma devi anche impedire di "leggere" oltre i limiti.
Il primo giro il valore è presente.
Ma il secondo giro non hai nessun valore, per cui TStringList ti segnala il problema.

Stilgar
Titolo: Re:DLL Profilabexpert
Inserito da: Simon75 - Maggio 17, 2013, 12:11:41 pm
Si... ma come faccio a impedire di leggere oltre i limiti?

Titolo: Re:DLL Profilabexpert
Inserito da: nomorelogic - Maggio 17, 2013, 01:22:50 pm
ci sono molti modi, prova questo

Codice: [Seleziona]


  procedure CaricaArrayDaFile(FileName: string; PAParams: PDLLParams);
  var
    i: integer;
    sl: TStringList;
    e: extended;
    s: string;
  begin
    sl := TStringList.Create;
    try
      try
        sl.LoadFromFile(FileName);
        for i := low(PAParams^) to high(PAParams^) do
        begin
          if not (i in [0..sl.count-1]) then
             break;

          s := sl.Values[IntToStr(i)];
          log(IntToStr(i) + ': valore = <' + s + '>');
          if s <> '' then
          begin
            e := StrToFloat(s);
            PAParams^[i] := e;
            log('   ' + IntToStr(i) + ' caricato');
          end
          else
          begin
            log('  ' + IntToStr(i) + ' non caricato');
          end;
        end;
  except
        on e: Exception do
        begin
          log('porca miseria! "' + e.message + '"');
          raise e;
        end;
      end;
    finally
      sl.Free;
    end;
  end;     
Titolo: Re:DLL Profilabexpert
Inserito da: Simon75 - Maggio 17, 2013, 01:57:44 pm
così non carica niente

Nome del file selezionato : C:\Documents and Settings\Simone\Desktop\dll\Prova.txt
POutput ok
0: valore = <>
  0 non caricato
Titolo: Re:DLL Profilabexpert
Inserito da: Simon75 - Maggio 17, 2013, 02:45:44 pm
No...scusatemi ho copiato per intero quanto scritto da nomore e non avevo modificato 

questa riga

Codice: [Seleziona]

s := sl.Values[IntToStr(i)];



in questa

Codice: [Seleziona]



 s := sl[i];




Ora l'errore non esce più e nella log vedo che carica ma nel display non vedo il risultato.

Codice: [Seleziona]


procedure CaricaArrayDaFile(FileName: string; PAParams: PDLLParams);
  var
    i: integer;
    sl: TStringList;
    e: extended;
    s: string;
  begin
    sl := TStringList.Create;
    try
      try
        sl.LoadFromFile(FileName);
        for i := low(PAParams^) to high(PAParams^) do
        begin
          if not (i in [0..sl.Count - 1]) then
            break;
          s := sl[i];

          // s := sl.Values[IntToStr(i)];
          log(IntToStr(i) + ': valore = <' + s + '>');
          if s <> '' then
          begin
            e := StrToFloat(s);
            PAParams^[i] := e;
            log('   ' + IntToStr(i) + ' caricato');
          end
          else
          begin
            log('  ' + IntToStr(i) + ' non caricato');
          end;
        end;
      except
        on e: Exception do
        begin
          log('porca miseria! "' + e.message + '"');
          raise e;
        end;
      end;
    finally
      sl.Free;
    end;
  end;


Nome del file selezionato : C:\Documents and Settings\Simone\Desktop\dll\Prova.txt
POutput ok
0: valore = <23>
   0 caricato
Titolo: Re:DLL Profilabexpert
Inserito da: Simon75 - Maggio 26, 2013, 12:24:56 am
Ciao  Stilgar e Nomore vi ringrazio molto funziona!!!
sbagliavo a inserire i dati di input li salvavo come numerici e poi pretendevo di visualizzarli come stringhe nel display stringa (sempre in Profilab)

Adesso ho due domade da farvi ancora:

1) Dovrei salvarli come stringhe e ho pensato di usare questo:

Codice: [Seleziona]

  TStringParams = array[0..100] of PChar;   //Type of ProfiLab DLL parameters
  PStringParams = ^TStringParams;        // Pointer to ProfiLab DLL parameters



2) Vorrei inserire un semplice ShowMessage nel momento che premo salva, giusto per capire se ha salvato. Ho provato ma genera un errore, forse nelle dll va usata sotto procedura?

Attualmente mi genera 2 errori di tipo ma non so come rimediare:



project1.lpr(130,22) Hint: Parameter "PInput" not used
project1.lpr(130,30) Hint: Parameter "POutput" not used
project1.lpr(130,39) Hint: Parameter "PUser" not used
project1.lpr(246,39) Error: Incompatible type for arg no. 2: Got "PStringParams", expected "PDLLParams"
project1.lpr(181,13) Hint: Found declaration: CaricaArrayDaFile(AnsiString,PDLLParams);
project1.lpr(257,38) Error: Incompatible type for arg no. 2: Got "PStringParams", expected "PDLLParams"
project1.lpr(138,13) Hint: Found declaration: SalvaArrayInFile(AnsiString,PDLLParams);
project1.lpr(286) Fatal: There were 2 errors compiling module, stopping



Codice: [Seleziona]


library project1;

{$mode objfpc}{$H+}

uses
  Interfaces,
  Classes,
  SysUtils,
  Windows,
  FileUtil,
  Forms,
  Controls,
  Graphics,
  Dialogs,
  ShellApi;

const
  Inputs = 3;  // quantita entrata
  Outputs = 1; // quantita uscita

  {INPUTS}// nome per numero di entrata
  I0 = 0;  // valore I0 = PInput[I0] ossia PInput[0]
  I1 = 1;  // valore I1 = PInput[I1] ossia PInput[1]
  Leggi = 2;
  // I3 = 3;
  // ... I99 = 99;

  {OUTPUTS}// nome per numero di uscita
  Stampa = 0;  // valore Q0 = POutput[Q0] ossia POutput[0]
  //Q1 = 1;  // valore Q1 = POutput[Q1] ossia POutput[1]

  // Q3 = 3;
  // ... Q99 = 99;

  {USER}// nome per numero di variabile, I valori vengono memorizzati

  U0 = 0; // valore U0 = PUser[U0] ossia PUser[0]
  // U1 = 1;
  // U2 = 2;
  // U3 = 3;
  // ... U99 = 99;

  // I0,I1,I2,I3,Q0,Q1,Q2,Q3,U0,U1,U2,U3
  // I nomi possono essere qualsiasi, sono case-insensitive
var
  globalDialog: TFileDialog;

type

  TDLLParams = array[0..100] of extended; //Type of ProfiLab DLL parameters
  PDLLParams = ^TDLLParams;               // Pointer to ProfiLab DLL parameters

  TStringParams = array[0..100] of PChar;   //Type of ProfiLab DLL parameters
  PStringParams = ^TStringParams;        // Pointer to ProfiLab DLL parameters


  function ApriSaveDialog: ShortString;

  begin
    Result := '';
    if not assigned(globalDialog) then
    begin
      globalDialog := TSaveDialog.Create(nil);
      try
        globalDialog.DefaultExt := 'txt';

        globalDialog.Filter := '*.txt';
        if globalDialog.Execute then
          Result := globalDialog.FileName
        else
          Result := '';
      finally
        FreeAndNil(globalDialog);
      end;
    end;
  end;




  function ApriOpenDialog: ShortString;
  begin
    Result := '';
    if not assigned(globalDialog) then
    begin
      globalDialog := TOpenDialog.Create(nil);
      try
        globalDialog.DefaultExt := 'txt';
        globalDialog.Filter := '*.txt';
        if globalDialog.Execute then
          Result := globalDialog.FileName
        else
          Result := '';
      finally
        FreeAndNil(globalDialog);
      end;
    end;
  end;

  function NumInputs: byte;
  begin
    Result := Inputs; // trasferire quantita entrata
  end;

  function NumOutputs: byte;
  begin
    Result := Outputs; // trasferire quantita uscita
  end;

  function InputName(Channel: byte): ShortString; // trasferire nome di entrata
  begin
    case Channel of
      I0: Result := 'I0'; // nome di pin I0
      I1: Result := 'I1'; // nome di pin I1
      Leggi: Result := '$Leggi';
    end;
  end;

  function OutputName(Channel: byte): ShortString; // trasferire nome di uscita
  begin
    case Channel of
      Stampa: Result := '$Stampa'; // nome di pin Q0
      //Q1: Result := 'Q1'; // nome di pin Q1
    end;
  end;




  procedure SimStart(PInput, POutput, PUser: PDLLParams);
  // Routine viene eseguita solo al primo avvio
  begin

  end;



  procedure SalvaArrayInFile(FileName: string;
    PAParams: PDLLParams);
  var
    i: integer;
    sl: TStringList;
  begin

    sl := TStringList.Create;
    try
      for i := 2 to 3 do
        // for i := low(PAParams^) to high(PAParams^) do

        if PAParams^[i] = 0 then


          sl.Add(FloatToStr(PAParams^[i]));


      sl.SaveToFile(FileName);
    finally
      sl.Free;
    end;

  end;

  procedure log(msg: string);
  begin
    AssignFile(Output, 'Debug.txt');
    if (FileExists('Debug.txt')) then
    begin
      Append(Output);
    end
    else
    begin
      Rewrite(Output);
    end;
    WriteLn(Output, msg);
    Flush(Output);
    CloseFile(Output);
  end;



  procedure CaricaArrayDaFile(FileName: string;
    PAParams: PDLLParams);
  var
    i: integer;
    sl: TStringList;
    e: extended;
    s: string;
  begin
    sl := TStringList.Create;
    try
      try
        sl.LoadFromFile(FileName);

        for i := low(PAParams^) to high(PAParams^) do
        begin
          if not (i in [0..sl.Count - 1]) then
            break;
          s := sl[i];

          // s := sl.Values[IntToStr(i)];
          log(IntToStr(i) + ': valore = <' + s + '>');
          if s <> '' then
          begin
            e := StrToFloat(s);
            PAParams^[i] := e;
            log('   ' + IntToStr(i) + ' caricato');
          end
          else
          begin
            log('  ' + IntToStr(i) + ' non caricato');
          end;
        end;
      except
        on e: Exception do
        begin
          log('porca miseria! "' + e.message + '"');
          raise e;
        end;
      end;
    finally
      sl.Free;
    end;
  end;


  procedure CalculateEx(PInput,POutput, PUser: PDLLParams; PStrings : PStringParams);
  // Routine è permanente
  var
    sl: TStringList;
    s: string;
  begin

    if PInput^[I0] > 2.5 then
    begin
      if (PInput^[I0] > 2.5) and not (PUser^[U0] > 2.5) then
      begin
        s := ApriOpenDialog;
        log('Nome del file selezionato : ' + s);
        if s <> '' then
        begin
          if assigned(POutput) then
            log('POutput ok')
          else
            raise Exception.Create('Non ci siamo');

          CaricaArrayDaFile(s,PStrings);
        end;
      end;
    end;
    PUser^[U0] := PInput^[I0];
    if PInput^[I1] > 2.5 then
    begin
      if (PInput^[I1] > 2.5) and not (PUser^[I1] > 2.5) then
      begin
        s := ApriSaveDialog;
        if s <> '' then
          SalvaArrayInFile(s,PStrings);
      end;
    end;
    PUser^[I1] := PInput^[I1];
  end;




  procedure SimStop(PInput, POutput, PUser: PDLLParams);
  // Routine viene eseguita solo in fase di chiusura
  begin

  end;


  //export methods for ProfiLab
exports
  SimStart,
  SimStop,
  NumInputs,
  NumOutputs,
  CalculateEx,
  InputName,
  OutputName,
  ApriOpenDialog,
  ApriSaveDialog;
begin
end.                     


Titolo: Re:DLL Profilabexpert
Inserito da: nomorelogic - Maggio 26, 2013, 10:38:14 am
la dichiarazione CaricaArrayDaFile è la seguente:
procedure CaricaArrayDaFile(FileName: string; PAParams: PDLLParams);
e si aspetta nr. 2 parametri: 1 di tipo string e 1 di tipo PDLLParams

quando la richiami con
CaricaArrayDaFile(s,PStrings);
stai passando 1 parametri di tipo string ed 1 di tipo PStringParams
il compilatore giustamente si incacchia

ora:
a prescindere da come li salvi sul file, in memoria , sono sempre rappresentati nello stesso modo (PAParams: PDLLParams).
Inoltre, una volta che sono un in file, è come se già fossero una stringa: è nel momento in cui li rileggi che devi preoccuparti di convertirli per poterli memorizzare.

Qual è il problema che vorresti risolvere quando dici che vorresti salvarli come stringhe?
Titolo: Re:DLL Profilabexpert
Inserito da: Simon75 - Maggio 27, 2013, 12:15:46 am
Non riesco a salvare numeri con il separatore ; e non riesco a salvare numeri con / esempio 3300/400 mi salva solo 3300 stessa cosa per il ; 4500;500 mi salva solo il 4500.

Stessa cosa per caricare, ho provato ad aprire il file txt e scriverci dentro i numeri 3434;456
e la log mi tira fuori questo

0: valore = <3434;456>
porca miseria! ""3434;456" is an invalid float"

Titolo: Re:DLL Profilabexpert
Inserito da: nomorelogic - Maggio 27, 2013, 09:36:07 am
intanto risolviamo il salvataggio, per il load lo vedremo quando il salvataggio funziona

nella procedura SalvaArrayInFile devi intervenire sull'istruzione seguente
Codice: [Seleziona]
sl.Add(FloatToStr(PAParams^[i]));


sl è una TStringList ed ovviamente il metodo Add come parametro richiede una stringa
è per questo che usi FloatToStr, per convertire PAParams^ in una stringa e per passarla poi come parametro ad Add
se devi salvare in quel formato che dici tu puoi fare qualcosa del genere:
Codice: [Seleziona]
sl.Add( '<' + FloatToStr(PAParams^[i]) + ';' +  FloatToStr("un altro numero") + '>' );
che altro non è che una concatenazione di stringhe

fatto questa modifica salva il file ma non ricaricarlo in memoria (viene letto un numero ed ora non ci sono numeri) ma vai a vedere nel file se tutto è ok
per il load, poi si vedrà
Titolo: Re:DLL Profilabexpert
Inserito da: Simon75 - Maggio 27, 2013, 11:26:19 am
Si nel file txt mi salva giusto, ho messo un numero a caso nelle parentesi:


Codice: [Seleziona]
 sl.Add( '<' + FloatToStr(PAParams^[i]) + ';' +  FloatToStr(3434) + '>' );



Il risultato:

<78;3434>


Titolo: Re:DLL Profilabexpert
Inserito da: nomorelogic - Maggio 27, 2013, 12:46:07 pm
altra domanda:
nel file il formato di salvataggio è sempre lo stesso?
tipo: <78;3434>

o c'è possibilità che a volte devi memorizzare altre combinazioni tipo
78
<434>
#78;3434/343#
Titolo: Re:DLL Profilabexpert
Inserito da: Simon75 - Maggio 27, 2013, 01:41:17 pm
Quello che andrò a salvare sarà es:

 2200;400;677 oppure 3300/400
Titolo: Re:DLL Profilabexpert
Inserito da: nomorelogic - Maggio 27, 2013, 02:48:50 pm
prova ad usare questa procedura
una cosa non mi è chiara: nella versione precedente leggevi un valore per riga e lo mettevi nella variabile 'e'.
ora i valori sono 2 o 3: è per questo che ho definito un array (nr) da 1 a tre
però non so cosa ci devi fare con i valori successivi al primo, quindi dovrai terminare tu la procedura.

NB: l'ho scritta su un text editor e non l'ho nè provata nè compilata...


Codice: [Seleziona]
procedure CaricaArrayDaFile(FileName: string;
    PAParams: PDLLParams);
  var
    i: integer;
    sl: TStringList;
    // e: extended;
    s: string;

sep: string;
p,idx: integer;
nr: array[1..3] of extended;
  begin
    sl := TStringList.Create;
    try
      try
        sl.LoadFromFile(FileName);

        for i := low(PAParams^) to high(PAParams^) do
        begin
          if not (i in [0..sl.Count - 1]) then
            break;
          s := sl[i];

          // s := sl.Values[IntToStr(i)];
          log(IntToStr(i) + ': valore = <' + s + '>');
          if s <> '' then
          begin
    sep := '';
p := pos('/', s);
    if p > 0 then
   sep := '/';
if p = 0 then begin
   p := pos(';', s);
   if p > 0 then
      sep := ';';
end;     
    if sep = '' then
   raise exception.create('impossibile determinare il tipo di tracciato record');
 
    for idx := 1 to 3 do
  nr[idx] := 0;
 
            idx := 0;
    repeat
   inc(idx);
   nr[idx] := StrToFloat(copy(s, 1, p-1));
   s := copy(s, p+1, length(s));    
   p := pos(sep, s);
until (s = '') or (p = 0);

            // e := StrToFloat(s); -> il primo numero è in nr[1]
            // PAParams^[i] := e;
            PAParams^[i] := nr[1];

            log('   ' + IntToStr(i) + ' caricato');
          end
          else
          begin
            log('  ' + IntToStr(i) + ' non caricato');
          end;
        end;
      except
        on e: Exception do
        begin
          log('porca miseria! "' + e.message + '"');
          raise e;
        end;
      end;
    finally
      sl.Free;
    end;
  end;
Titolo: Re:DLL Profilabexpert
Inserito da: Simon75 - Maggio 28, 2013, 09:04:35 pm
OK ho risolto  in SalvaArrayInFile e mi salva correttamente: 3300;400....

ora questo 3300;400 non gli va bene quando lo carico e dalla log  mi esce:

0: valore = <3300;400>
porca miseria! ""3300;400" is an invalid float"

Codice: [Seleziona]

procedure CaricaArrayDaFile(FileName: string; PAParams: PDLLParams; PStringParams:PStringParams);
  var
    i: integer;
    sl: TStringList;
    e: extended;
    s: string;
  begin
        sl := TStringList.Create;
    try
      try
        sl.LoadFromFile(FileName);
         //for i := 0 to 1 do
        for i := low(PAParams^) to high(PAParams^) do
        begin
          if not (i in [0..sl.Count - 1]) then
            break;
          s := sl[i];

          // s := sl.Values[IntToStr(i)];
          log(IntToStr(i) + ': valore = <' + s + '>');
          if s <> '' then
          begin
            e := strtofloat(s);
            PAParams^[i] := e;
            log('   ' + IntToStr(i) + ' caricato');
          end
          else
          begin
            log('  ' + IntToStr(i) + ' non caricato');
          end;
        end;
      except
        on e: Exception do
        begin
          log('porca miseria! "' + e.message + '"');
          raise e;
        end;
      end;
    finally
      sl.Free;
    end;
  end;

Titolo: Re:DLL Profilabexpert
Inserito da: nomorelogic - Maggio 29, 2013, 10:19:42 am
devi provare CaricaArrayDaFile che trovi nel mio post precedente
Titolo: Re:DLL Profilabexpert
Inserito da: Simon75 - Maggio 30, 2013, 08:44:05 am
Si non mi da più errore, e vedo che carica dalla log ma non leggo niente nel display...

Per riuscire a leggere nel display dovrei usare questo:

Codice: [Seleziona]
     TStringParams = array[0..100] of PChar;   //Type of ProfiLab DLL parameters
  PStringParams = ^TStringParams;        // Pointer to ProfiLab DLL parameters

In CaricaArrayDaFile  attualmente gli sto passando  PStringParams  ma non viene usato, come posso usarlo?


Codice: [Seleziona]
procedure CaricaArrayDaFile(FileName: string;
    PAParams: PDLLParams; PStringParams: PStringParams);
  var
    i: integer;
    sl: TStringList;
    // e: extended;
    s: string;

    sep: string;
    p,idx: integer;
    nr: array[1..3] of extended;
  begin
    sl := TStringList.Create;
    try
      try
        sl.LoadFromFile(FileName);

        for i := low(PAParams^) to high(PAParams^) do
        begin
          if not (i in [0..sl.Count - 1]) then
            break;
            s := sl[i];

          //s := sl.Values[IntToStr(i)];
          log(IntToStr(i) + ': valore = <' + s + '>');
          if s <> '' then
          begin
            sep := '';
            p := pos('/', s);
            if p > 0 then
               sep := '/';
            if p = 0 then begin
               p := pos(';', s);
               if p > 0 then
                  sep := ';';
            end;
            if sep = '' then
               raise exception.create('impossibile determinare il tipo di tracciato record');

            for idx := 1 to 3 do
              nr[idx] := 0;

            idx := 0;
            repeat
               inc(idx);
               nr[idx] := StrToFloat(copy(s, 1, p-1));
               s := copy(s, p+1, length(s));
               p := pos(sep, s);
            until (s = '') or (p = 0);

            // e := StrToFloat(s); -> il primo numero è in nr[1]
            // PAParams^[i] := e;
            PStringParams^[i] := nr[1];

            log('   ' + IntToStr(i) + ' caricato');
          end
          else
          begin
            log('  ' + IntToStr(i) + ' non caricato');
          end;
        end;
      except
        on e: Exception do
        begin
          log('porca miseria! "' + e.message + '"');
          raise e;
        end;
      end;
    finally
      sl.Free;
    end;
  end;


Grazie
Titolo: Re:DLL Profilabexpert
Inserito da: Simon75 - Maggio 31, 2013, 02:52:02 pm
Avete idea di come mai lo vedo caricare nella log ma non nei display?

Ho fatto questa modifica:

Codice: [Seleziona]

    procedure CaricaArrayDaFile(FileName: string; PAParams: PDLLParams; PStringParams:PStringParams);
  var
    i: integer;
    sl: TStringList;
  //  e: extended;
    s: string;
  begin
        sl := TStringList.Create;  // istanzio l'oggetto
    try
      try
        sl.LoadFromFile(FileName);  // carico il file
         for i := 0 to 0 do         // cerco il file da caricare
        //for i := low(PAParams^) to high(PAParams^) do
        begin
          if not (i in [0..sl.Count - 1]) then
            break;
         s := sl[i];

          //s := sl.Values[IntToStr(i)];
          log(IntToStr(i) + ': valore = <' + s + '>');
          if s <> '' then       // se cè qualcosa allora
          begin
         // e := strtofloat(s);  // converto s da stinga float e l'assegno a extended
          sl.Add(PStringParams^[i]);

            //PAParams^[i] := e;
            log('   ' + IntToStr(i) + ' caricato');
          end
          else
          begin
            log('  ' + IntToStr(i) + ' non caricato');
          end;
        end;
      except
        on e: Exception do
        begin
          log('porca miseria! "' + e.message + '"');
          raise e;
        end;
      end;
    finally
      sl.Free;
    end;
  end;   
Titolo: Re:DLL Profilabexpert
Inserito da: Simon75 - Giugno 04, 2013, 10:07:33 am
Ciao,

Ho provato in questo modo non da errori  ma non vedo niente nel display.

Ho provato a inserire un vettore stringa nella varibile globale poichè penso che s occupa sempre la stessa area di RAM e al massimo alla fine della procedura lì il programma troverebbe solo l'ultimo valore; in realtà neppure quello perchè terminata la procedura s in quanto variabile locale SPARISCE



Codice: [Seleziona]

var
  globalDialog: TFileDialog;
  i: integer;
  stringhe: array [0..100] of string;

Poi ho modificato CaricaArryDaFile così:
Codice: [Seleziona]
procedure CaricaArrayDaFile(FileName: string; PAParams: PDLLParams; PStringParams:PStringParams);
  var
    //i: integer;
    sl: TStringList;
    //e: extended;
    s: string;
  begin
        sl := TStringList.Create;
    try
      try
        sl.LoadFromFile(FileName);
        for i := 0 to 1 do
        //for i := low(PStringParams^) to high(PStringParams^) do
        begin
          if not (i in [0..sl.Count - 1]) then
            break;

         s := sl[i];
         //s[LastDelimiter(';',s)]:=',';

          log(IntToStr(i) + ': valore = <' + s + '>');
          if s <> '' then
          begin
          stringhe[i]:=s;
          PStringParams^[i] := PChar(stringhe[i]);

         
           log('   ' + IntToStr(i) + ' caricato');
          end
          else
          begin
            log('  ' + IntToStr(i) + ' non caricato');
          end;
        end;
      except
        on e: Exception do
        begin
          log('porca miseria! "' + e.message + '"');
          raise e;
        end;
      end;
    finally
      sl.Free;
    end;
  end;


Ora la mia domanda è per voi ci sono altre modifiche da fare? 
 
Come si esegue un debug per una DLL?

Vi ringrazio.
Titolo: Re:DLL Profilabexpert
Inserito da: Simon75 - Giugno 08, 2013, 03:09:01 pm
Allora ho fatto il debug e vedo che carica correttamente, il problema è su procedure CalculateEx,

Questo è l'aiuto che mi è stato dato :

I see one basic big fault:

Note that $Inputs and $Output share the SAME(!)  PString-pointer.

- PString is filled with Input-Strings by PL before calculateEx is invoked.
- PStrings MUST be filled with output-strings BEFORE calculateEx is left - in ANY case (!!!) and not just under certain circumstances.

if no action is taken in calculateEx-> output$[index] returns input$[index] (which may be nothing as input[index] is numeric).


Codice: [Seleziona]

library project1;

{$mode objfpc}{$H+}

uses
  Interfaces,
  Classes,
  SysUtils,
  Windows,
  FileUtil,
  Forms,
  Controls,
  Graphics,
  Dialogs,
  ShellApi;

const
  Inputs = 3;  // quantita entrata
  Outputs = 1; // quantita uscita

  {INPUTS}// nome per numero di entrata
  I0 = 0;  // valore I0 = PInput[I0] ossia PInput[0]
  I1 = 1;  // valore I1 = PInput[I1] ossia PInput[1]
  Leggi = 2;
  // I3 = 3;
  // ... I99 = 99;

  {OUTPUTS}// nome per numero di uscita
  Stampa = 0;  // valore Q0 = POutput[Q0] ossia POutput[0]
  //Q1 = 1;  // valore Q1 = POutput[Q1] ossia POutput[1]

  // Q3 = 3;
  // ... Q99 = 99;

  {USER}// nome per numero di variabile, I valori vengono memorizzati

  U0 = 0; // valore U0 = PUser[U0] ossia PUser[0]
  // U1 = 1;
  // U2 = 2;
  // U3 = 3;
  // ... U99 = 99;

  // I0,I1,I2,I3,Q0,Q1,Q2,Q3,U0,U1,U2,U3
  // I nomi possono essere qualsiasi, sono case-insensitive
var
  globalDialog: TFileDialog;
  i: integer;
  stringhe: array [0..100] of ShortString;


type

  TDLLParams = array[0..100] of extended; //Type of ProfiLab DLL parameters
  PDLLParams = ^TDLLParams;               // Pointer to ProfiLab DLL parameters

  TStringParams = array[0..100] of PChar;   //Type of ProfiLab DLL parameters
  PStringParams = ^TStringParams;        // Pointer to ProfiLab DLL parameters


  function ApriSaveDialog: ShortString;

  begin
    Result := '';
    if not assigned(globalDialog) then
    begin
      globalDialog := TSaveDialog.Create(nil);
      try
        globalDialog.DefaultExt := 'txt';

        globalDialog.Filter := '*.txt';
        if globalDialog.Execute then
          Result := globalDialog.FileName
        else
          Result := '';
      finally
        FreeAndNil(globalDialog);
      end;
    end;
  end;




  function ApriOpenDialog: ShortString;
  begin
    Result := '';
    if not assigned(globalDialog) then
    begin
      globalDialog := TOpenDialog.Create(nil);
      try
        globalDialog.DefaultExt := 'txt';
        globalDialog.Filter := '*.txt';
        if globalDialog.Execute then
          Result := globalDialog.FileName
        else
          Result := '';
      finally
        FreeAndNil(globalDialog);
      end;
    end;
  end;

  function NumInputs: byte;
  begin
    Result := Inputs; // trasferire quantita entrata
  end;

  function NumOutputs: byte;
  begin
    Result := Outputs; // trasferire quantita uscita
  end;

  function InputName(Channel: byte): ShortString; // trasferire nome di entrata
  begin
    case Channel of
      I0: Result := 'I0'; // nome di pin I0
      I1: Result := 'I1'; // nome di pin I1
      Leggi: Result := '$Leggi';
    end;
  end;

  function OutputName(Channel: byte): ShortString; // trasferire nome di uscita
  begin
    case Channel of
      Stampa: Result := '$Stampa'; // nome di pin Q0
      //Q1: Result := 'Q1'; // nome di pin Q1
    end;
  end;




  procedure SimStart(PInput, POutput, PUser: PDLLParams);
  // Routine viene eseguita solo al primo avvio
  begin

  end;



  procedure SalvaArrayInFile(FileName: string; PAParams: PDLLParams;PStringParams:PStringParams);
  var
    i: integer;
    sl: TStringList;
  begin

    sl := TStringList.Create;
    try
      for i := 2 to 3 do


        if PAParams^[i] <> 0 then



           sl.Add(PStringParams^[i]);




      sl.SaveToFile(FileName);
    finally
      sl.Free;
    end;

  end;

  procedure log(msg: string);
  begin
    AssignFile(Output, 'Debug.txt');
    if (FileExists('Debug.txt')) then
    begin
      Append(Output);
    end
    else
    begin
      Rewrite(Output);
    end;
    WriteLn(Output, msg);
    Flush(Output);
    CloseFile(Output);
  end;







procedure CaricaArrayDaFile(FileName: string; PAParams: PDLLParams; PStringParams:PStringParams);
  var

    sl: TStringList;

    s: string;
  begin
        sl := TStringList.Create;
    try
      try
        sl.LoadFromFile(FileName);
      for i := 0 to 1 do

        begin
          if not (i in [0..sl.Count - 1]) then
            break;
          s:= sl[i];
          stringhe[i]:=s;

          log(IntToStr(i) + ': valore = <' + s + '>');
          if s <> '' then
          begin



            PStringParams^[i] := @stringhe[i];




            log('   ' + IntToStr(i) + ' loaded');
          end
          else
          begin
            log('  ' + IntToStr(i) + ' not loaded');
          end;
        end;
      except
        on e: Exception do
        begin
          log('Attention! "' + e.message + '"');
          raise e;
        end;
      end;
    finally
      sl.Free;
    end;
  end;






  procedure CalculateEx(PInput, POutput, PUser: PDLLParams; PStringParams:PStringParams);
  // Routine è permanente
  var
    sl: TStringList;
    s: string;
  begin

    if PInput^[I0] > 2.5 then
    begin
      if (PInput^[I0] > 2.5) and not (PUser^[U0] > 2.5) then
      begin
        s := ApriOpenDialog;
        log('Nome del file selezionato : ' + s);
        if s <> '' then
        begin
          if assigned(POutput) then
            log('POutput ok')
          else
            raise Exception.Create('Non ci siamo');

          CaricaArrayDaFile(s, POutput,PStringParams);
        end;
      end;
    end;
    PUser^[U0] := PInput^[I0];
    if PInput^[I1] > 2.5 then
    begin
      if (PInput^[I1] > 2.5) and not (PUser^[I1] > 2.5) then
      begin
        s := ApriSaveDialog;
        if s <> '' then
          SalvaArrayInFile(s, PInput,PStringParams);
      end;
    end;
    PUser^[I1] := PInput^[I1];
  end;




  procedure SimStop(PInput, POutput, PUser: PDLLParams);
  // Routine viene eseguita solo in fase di chiusura
  begin

  end;


  //export methods for ProfiLab
exports
  SimStart,
  SimStop,
  NumInputs,
  NumOutputs,
  CalculateEx,
  InputName,
  OutputName,
  ApriOpenDialog,
  ApriSaveDialog;
begin
end.


Titolo: Re:DLL Profilabexpert
Inserito da: Simon75 - Giugno 11, 2013, 04:01:17 pm
Ringrazio tutti ho risolto
Titolo: Re:DLL Profilabexpert
Inserito da: nomorelogic - Giugno 12, 2013, 03:20:54 pm
questa è un'ottima notizia
ci dici dove stava l'inghippo? :)