Italian community of Lazarus and Free Pascal

Programmazione => Generale => Topic aperto da: Simon75 - Gennaio 01, 2013, 01:23:56 am

Titolo: DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 01, 2013, 01:23:56 am
Salve Signori  :)  quello che devo fare è dire alla SaveDialog di salvare quello che scrivo dentro le caselle nere e poi dire a OpenDialog di caricare il file di testo salvato con SaveDialog.
Non fate caso a ADD e PART loro fanno il loro lavoro poichè ADD mi genera la stringa creata da me nelle caselle nere ovvero le aggiunge e PART le divide in poche parole ho bisogno di un terzo ingresso che mi legga la riga di testo che esce da ADD $  e penso di usare un semplice read per tale scopo e un uscita con write che andra sull'ingresso $ di PART.
Posso usare assieme:

Codice: [Seleziona]
     

type TDLLParams = array[0..100] of extended;
     PDLLParams = ^TDLLParams;


type TStringParams = array[0..100] of PChar;
     PStringParams = ^TStringParams;


Anche perché dice questo:

The procedure CALCULATE is called repeatedly while ProfiLab is in RUN mode, to hand out new input values to the DLL and to request new output values from the DLL. This means that this procedure must be programmed as short as possible, and must not contain any pauses (WAIT loops or SLEEP commands) that waste time. After reading input values and setting new output vaues this routine should be terminated as soon as possible. The time spent in this procedure will directly influence the simulation frequency of ProfiLab.
 
Codice: [Seleziona]
Procedure CalculateEx(PInput,POutput,PUser: PDLLParams; PStrings: PStringParams);

This method was introduced to allow string processing with DLL´s. It may be used as alternative for CALCULATE. Parameter PSTRINGS were added for interfacing string data. Its Delphi delclaration is as follows:
 
Codice: [Seleziona]
type TStringParams = array[0..100] of PChar;
     PStringParams = ^TStringParams;



Each input/output (max. 100) has a null-terminated character pointer (PChar) assigned, which points to a memory space that is provided by ProfiLab. Right before ProfiLab enters the method, data is fetched from the $inputs. After leaving the method data is handed out through the $outputs. It is not distinguished between inputs and outputs. This means that Input 0 and Output 0 for example share the same PChar. To make a pin become a string input or string output its pin name must be declared with a leading '$' character. Examples for string processing with DLL´s and ProfiLab are available.
 


Ringrazio

Codice: [Seleziona]

library dialog;

{$mode objfpc}{$H+}

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

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]
  $read = 2;
  // I3 = 3;
  // ... I99 = 99;

  {OUTPUTS}// nome per numero di uscita
  $write = 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;
     PStringParams = ^TStringParams;


  function ApriSaveDialog: ShortString;
  begin
    result := '';
    if not assigned(globalDialog) then
    begin
      globalDialog := TSaveDialog.Create(nil);
      try
        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.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
      $read: Result:='$read';
    end;
  end;

  function OutputName(Channel: byte): ShortString; // trasferire nome di uscita
  begin
    case Channel of
      $write: Result := '$write'; // 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 Calculate(PInput, POutput, PUser: PDLLParams); // Routine è permanente
  begin
    if PInput^[I0] > 2.5 then
    begin
      if ('' <> ApriOpenDialog) then
     end;
      if PInput^[I1] > 2.5 then
    begin
      if ('' <> ApriSaveDialog) then
       end;
       end;
Procedure CalculateEx(PInput,POutput,PUser: PDLLParams; PStrings: PStringParams);


begin

PInput^[$read]:=read;

POutput^[$write]:=write;


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,
  Calculate,
  InputName,
  OutputName,
  ApriOpenDialog,
  ApriSaveDialog;
begin
end.
             


Attualmente mi genera questo errore:
Codice: [Seleziona]


project1.lpr(24,3) Fatal: Syntax error, "BEGIN" expected but "ordinal const" found



(http://i47.tinypic.com/au79e8.png)


(http://i50.tinypic.com/x1ee6x.png)
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Stilgar - Gennaio 01, 2013, 12:11:56 pm
Codice: [Seleziona]
  $read = 2;
  // I3 = 3;
  // ... I99 = 99;

  {OUTPUTS}// nome per numero di uscita
  $write = 0;  // valore Q0 = POutput[Q0] ossia POutput[0]       
Ciao,
 il problema è l'uso del carattere $ ...
Non è un carattere valido per gli identificatori.
Se lo usi davanti ai numeri ottieni che il compilatore non interpreta le cifre in decimale ma in esadecimale.
Il "#" viene usato per definire i caratteri via decimale o "#$" in esadecimale.

In altri linguaggi il $ viene utilizzato come carattere per gli identificatori. Non il pascal (non mi risulta nemmeno Java e C/C++ permettano di usarlo).

Ciao e buon anno
Stilgar
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 01, 2013, 02:38:09 pm
OK, ora in queste condizioni mi genera senza errori la DLL ma ora rimane il problema che devo dire a SaveDialog di salvare quello che scrivo nelle caselle nere e dire a OpenDialog di cercare il file salvato che mi serve da caricare nelle caselle grigie.
 ;)

Codice: [Seleziona]


library dialog;

{$mode objfpc}{$H+}

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

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]
  read = 2;
  // I3 = 3;
  // ... I99 = 99;

  {OUTPUTS}// nome per numero di uscita
  write = 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;
     PStringParams = ^TStringParams;


  function ApriSaveDialog: ShortString;
  begin
    result := '';
    if not assigned(globalDialog) then
    begin
      globalDialog := TSaveDialog.Create(nil);
      try
        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.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
      read: Result:='$read';
    end;
  end;

  function OutputName(Channel: byte): ShortString; // trasferire nome di uscita
  begin
    case Channel of
      write: Result := '$write'; // 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 Calculate(PInput, POutput, PUser: PDLLParams); // Routine è permanente
  begin
    if PInput^[I0] > 2.5 then
    begin
      if ('' <> ApriOpenDialog) then
     end;
      if PInput^[I1] > 2.5 then
    begin
      if ('' <> ApriSaveDialog) then
       end;
       end;
Procedure CalculateEx(PInput,POutput,PUser: PDLLParams; PStrings: PStringParams);


begin

PInput^[read]:=read;

POutput^[write]:=write;


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,
  Calculate,
  InputName,
  OutputName,
  ApriOpenDialog,
  ApriSaveDialog;
begin
end.
         



Codice: [Seleziona]

 
 if ApriSaveDialog.Execute then
    PInput^[read].Lines.SaveToFile( ApriSaveDialog.Filename );
 end;

if ApriOpenDialog.Execute then
    POutput^[write].Lines.LoadToFile( ApriOpenDialog.Filename );
 end;


Dovrebbe uscire cosi giusto?
E dovrei metterlo in Calculate
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: nomorelogic - Gennaio 01, 2013, 02:45:13 pm

if ApriOpenDialog.Execute then
    POutput^[write].Lines.LoadToFile( ApriOpenDialog.Filename );
 end;


a patto che LoadToFile diventi LoadFromFile, si può anche provare ;)
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 01, 2013, 03:03:41 pm
Mi genera questo Errori:

Codice: [Seleziona]

project1.lpr(120,22) Hint: Parameter "PInput" not used
project1.lpr(120,30) Hint: Parameter "POutput" not used
project1.lpr(120,39) Hint: Parameter "PUser" not used
project1.lpr(133,20) Error: Illegal qualifier
project1.lpr(134,19) Error: Illegal qualifier
project1.lpr(134,52) Error: Illegal qualifier
project1.lpr(137,19) Error: Illegal qualifier
project1.lpr(138,12) Error: Identifier not found "POutput"
project1.lpr(138,56) Error: Illegal qualifier
project1.lpr(139,5) Fatal: Syntax error, "." expected but ";" found


Codice: [Seleziona]

procedure Calculate(PInput, POutput, PUser: PDLLParams); // Routine è permanente



begin

 if ApriSaveDialog.Execute then
    PInput^[read].Lines.SaveToFile( ApriSaveDialog.Filename );
 end;
begin
if ApriOpenDialog.Execute then
    POutput^[write].Lines.LoadFromFile( ApriOpenDialog.Filename );
 end;

 if PInput^[I0] > 2.5 then
    begin
      if ('' <> ApriOpenDialog) then
     end;
      if PInput^[I1] > 2.5 then

begin
      if ('' <> ApriSaveDialog) then

       end;
       end;

Procedure CalculateEx(PInput,POutput,PUser: PDLLParams; PStrings: PStringParams);


begin

PInput^[read]:=read;

POutput^[write]:=write;


end; 


Avete qualche idea???
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: nomorelogic - Gennaio 01, 2013, 03:21:24 pm
c'è un po' di confusione nei begin/end e soprattutto le identazioni lasciano a desiderare e diventa più difficile capire cosa volevi scrivere :)

ad esempio cambia l'inizio come sotto e poi dai una sistemata anche al resto ;)

Codice: [Seleziona]

procedure Calculate(PInput, POutput, PUser: PDLLParams); // Routine è permanente
begin

if ApriSaveDialog.Execute then
    PInput^[read].Lines.SaveToFile( ApriSaveDialog.Filename );

if ApriOpenDialog.Execute then
    POutput^[write].Lines.LoadFromFile( ApriOpenDialog.Filename );



Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 01, 2013, 06:30:55 pm
Cosa cavolo sto sbagliando  :o mi metto a piangere adesso  :'(   :)

Codice: [Seleziona]

project1.lpr(120,22) Hint: Parameter "PInput" not used
project1.lpr(120,30) Hint: Parameter "POutput" not used
project1.lpr(120,39) Hint: Parameter "PUser" not used
project1.lpr(127,29) Hint: Parameter "POutput" not used
project1.lpr(127,38) Hint: Parameter "PUser" not used
project1.lpr(147,25) Error: Illegal qualifier
project1.lpr(148,25) Error: Illegal qualifier
project1.lpr(148,58) Error: Illegal qualifier
project1.lpr(151,25) Error: Illegal qualifier
project1.lpr(152,27) Error: Illegal qualifier
project1.lpr(152,62) Error: Illegal qualifier
project1.lpr(182) Fatal: There were 6 errors compiling module, stopping



Codice: [Seleziona]


procedure Calculate(PInput, POutput, PUser: PDLLParams); // Routine è permanente

begin

if PInput^[I0] > 2.5 then
    begin
      if ('' <> ApriOpenDialog) then
     end;
      if PInput^[I1] > 2.5 then
     begin
      if ('' <> ApriSaveDialog) then

       end;
       end;


Procedure CalculateEx(PInput,POutput,PUser: PDLLParams; PStrings: PStringParams);


begin
      if ApriSaveDialog.Execute then
          PInput^[read].Lines.SaveToFile( ApriSaveDialog.Filename );


      if ApriOpenDialog.Execute then
          POutput^[write].Lines.LoadFromFile( ApriOpenDialog.Filename );


PInput^[read]:=read;

POutput^[write]:=write;

end;   
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: nomorelogic - Gennaio 01, 2013, 07:43:09 pm
credo che il compilatore non capisca i blocchi begin/end ed effettivamente non è che si capisce cosa vuol dire:
if PInput^[I0] > 2.5 then
    begin
      if ('' <> ApriOpenDialog) then // qua c'è un "then" seguito da un "end"
     end;
      if PInput^[I1] > 2.5 then
     begin
      if ('' <> ApriSaveDialog) then // stesso errore di sopra

       end;


parti da questa versione sotto, quando compila senza errori, inserisci una istruzione alla volta. è il modo migliore per capire quando scrivi qualcosa di sbagliato ;)


Codice: [Seleziona]
procedure Calculate(PInput, POutput, PUser: PDLLParams); // Routine è permanente
begin

   if PInput^[I0] > 2.5 then
       begin
       end;

end;

Procedure CalculateEx(PInput,POutput,PUser: PDLLParams; PStrings: PStringParams);
begin
      if ApriSaveDialog.Execute then
          PInput^[read].Lines.SaveToFile( ApriSaveDialog.Filename );

      if ApriOpenDialog.Execute then
          POutput^[write].Lines.LoadFromFile( ApriOpenDialog.Filename );

      PInput^[read]:=read;

      POutput^[write]:=write;
end;   
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Stilgar - Gennaio 01, 2013, 10:14:38 pm
Simon, preferivo l'operazionale come avatar ;)
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 01, 2013, 11:04:55 pm
l'oscilloscopio per me è elettronica :)
Se non vedi i segnali che escono da un circuito come fai a quantificare le sue caratteristiche?
In laboratorio per me è il pane :)
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 02, 2013, 12:38:16 am
Mi sto perdendo  :-\
Perché non compila?

Codice: [Seleziona]

project1.lpr(121,22) Hint: Parameter "PInput" not used
project1.lpr(121,30) Hint: Parameter "POutput" not used
project1.lpr(121,39) Hint: Parameter "PUser" not used
project1.lpr(128,29) Hint: Parameter "POutput" not used
project1.lpr(128,38) Hint: Parameter "PUser" not used
project1.lpr(148,25) Error: Illegal qualifier
project1.lpr(149,25) Error: Illegal qualifier
project1.lpr(149,58) Error: Illegal qualifier
project1.lpr(152,25) Error: Illegal qualifier
project1.lpr(153,27) Error: Illegal qualifier
project1.lpr(153,62) Error: Illegal qualifier
project1.lpr(183) Fatal: There were 6 errors compiling module, stopping



Codice: [Seleziona]


procedure Calculate(PInput, POutput, PUser: PDLLParams); // Routine è permanente

begin

    if PInput^[I0] > 2.5 then ApriOpenDialog;

    if PInput^[I1] > 2.5 then ApriSaveDialog;



end;




Procedure CalculateEx(PInput,POutput,PUser: PDLLParams; PStrings: PStringParams);


begin

      if ApriSaveDialog.Execute then
          PInput^[read].Lines.SaveToFile( ApriSaveDialog.Filename );


      if ApriOpenDialog.Execute then
          POutput^[write].Lines.LoadFromFile( ApriOpenDialog.Filename );


PInput^[read]:=read;

POutput^[write]:=write;

end;
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Stilgar - Gennaio 02, 2013, 12:43:58 am
Hai controllato alle righe indicate cosa c'è?
Ctrl+G
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 02, 2013, 12:49:14 am
mi evidenzia questi:

Codice: [Seleziona]

      if ApriSaveDialog.Execute then
          PInput^[read].Lines.SaveToFile( ApriSaveDialog.Filename );


      if ApriOpenDialog.Execute then 
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Stilgar - Gennaio 02, 2013, 12:53:39 am
Ok, allora mi viene da pensare che "read" non sia dichiarata ...
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Stilgar - Gennaio 02, 2013, 12:55:00 am
Il numero di errori che ti segnala è compatibile con il fatto che read e write non siano dichiarate.
Le usi 3 volte e sono 2 variabili ... quindi i sei errori che ti segnala potrebbero essere questi.
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 02, 2013, 01:44:09 am
Ecco è leggermente peggiorato


Codice: [Seleziona]

project1.lpr(122,22) Hint: Parameter "PInput" not used
project1.lpr(122,30) Hint: Parameter "POutput" not used
project1.lpr(122,39) Hint: Parameter "PUser" not used
project1.lpr(129,31) Hint: Parameter "POutput" not used
project1.lpr(129,40) Hint: Parameter "PUser" not used
project1.lpr(150,23) Error: Illegal qualifier
project1.lpr(151,15) Warning: Local variable "Read" does not seem to be initialized
project1.lpr(151,19) Error: Incompatible types: got "AnsiString" expected "ShortInt"
project1.lpr(151,53) Error: Illegal qualifier
project1.lpr(151,62) Error: Illegal expression
project1.lpr(154,23) Error: Illegal qualifier
project1.lpr(155,16) Warning: Local variable "Write" does not seem to be initialized
project1.lpr(155,21) Error: Incompatible types: got "AnsiString" expected "ShortInt"
project1.lpr(155,57) Error: Illegal qualifier
project1.lpr(155,66) Error: Illegal expression
project1.lpr(158,17) Error: Incompatible types: got "AnsiString" expected "ShortInt"
project1.lpr(160,19) Error: Incompatible types: got "AnsiString" expected "ShortInt"
project1.lpr(197) Fatal: There were 10 errors compiling module, stopping

Codice: [Seleziona]


  procedure CalculateEx(PInput, POutput, PUser: PDLLParams; PStrings: PStringParams);
  var
    Read: string;
    Write: string;
  begin

    if ApriSaveDialog.Execute then
      PInput^[Read].Lines.SaveToFile(ApriSaveDialog.Filename);


    if ApriOpenDialog.Execute then
      POutput^[Write].Lines.LoadFromFile(ApriOpenDialog.Filename);


    PInput^[Read] := Read;

    POutput^[Write] := Write;

  end;
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 02, 2013, 01:46:29 am
Questo è tutto il codice

Codice: [Seleziona]


library dialog;

{$mode objfpc}{$H+}

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

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]
  Read = 2;
  // I3 = 3;
  // ... I99 = 99;

  {OUTPUTS}// nome per numero di uscita
  Write = 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.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.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
      Read: Result := '$read';
    end;
  end;

  function OutputName(Channel: byte): ShortString; // trasferire nome di uscita
  begin
    case Channel of
      Write: Result := '$write'; // 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 Calculate(PInput, POutput, PUser: PDLLParams); // Routine è permanente

  begin

    if PInput^[I0] > 2.5 then
      ApriOpenDialog;

    if PInput^[I1] > 2.5 then
      ApriSaveDialog;

  end;




  procedure CalculateEx(PInput, POutput, PUser: PDLLParams; PStrings: PStringParams);
  var
    Read: string;
    Write: string;
  begin

    if ApriSaveDialog.Execute then
      PInput^[Read].Lines.SaveToFile(ApriSaveDialog.Filename);


    if ApriOpenDialog.Execute then
      POutput^[Write].Lines.LoadFromFile(ApriOpenDialog.Filename);


    PInput^[Read] := Read;

    POutput^[Write] := Write;

  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,
  Calculate,
  InputName,
  OutputName,
  ApriOpenDialog,
  ApriSaveDialog;
begin
end.

               


Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Stilgar - Gennaio 02, 2013, 01:53:20 am
Simon ... dai ammettilo... scrivi codice a caso per prenderci in giro ...
Prima dichiari le costanti come numeri, adesso come variabili stringa ;)
Per poi usarli come numeri :D
Codice: [Seleziona]
var
    Read: string;
    Write: string;
  begin

    if ApriSaveDialog.Execute then
      PInput^[Read].Lines.SaveToFile(ApriSaveDialog.Filename);
Te lo dice anche il compilatore ;)
Codice: [Seleziona]
project1.lpr(151,15) Warning: Local variable "Read" does not seem to be initialized
project1.lpr(151,19) Error: Incompatible types: got "AnsiString" expected "ShortInt"
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 02, 2013, 01:59:34 am
Si ma ho bisogno di stringhe non numeri, vuoi dire che devo convertire a monte le costanti????
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Stilgar - Gennaio 02, 2013, 02:04:10 am
No, Simon non hai affatto bisogno di stringe ...
hai bisogno di numeri.
Stai andando ad usarli come indici di un array.
Gli array vogliono la posizione ...
Metti
Read :=0;
Write := 0;

Codice: [Seleziona]
    PInput^[Read] := Read;
    POutput^[Write] := Write;

Poi se vuoi fare altro ... questo non lo so, ma dal tuo codice ... ti servono "Word".
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Legolas - Gennaio 02, 2013, 10:20:29 am
Poi ci sono almeno altri due errori:

ApriOpenDialog.filename
ApriSaveDialog.filename

Per fare quello che stai facendo dovresti modificare le funzioni per far restituire TFileDialog.

Ancora: PInput e POutput non hanno la proprietà Lines. Sono dei semplici array, che stai utilizzando come se fossero dei TMemo

Come ti ha suggerito Stilgar nell'altro thread, se non vuoi impazzire e procedere a tentativi ti conviene mettere mano a un tutorial di base ("Essential Pascal" e "Essential Delphi" di Marco Cantù potrebbero fare al caso tuo)
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 02, 2013, 04:13:41 pm
Salve a tutti,  ma se devo acquisire stringhe e numeri dall'ingresso read e poi salvarle con savedialog non ho bisogno di variabili:string?
I puntatori cosi configurati non dovrebbero darmi problemi o sbaglio?
Codice: [Seleziona]

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

Voglio usare read per prendere il dato dall'utente ovvero caselle nere e acquisire con le caselle grigie i dati salvati con savedialog.
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: nomorelogic - Gennaio 02, 2013, 04:59:47 pm
per salvare un array in una lista di stringhe dovresti fare qualcosa del genere:
Codice: [Seleziona]
var i:integer;
sl: TStringList;
begin
  sl := TStringList.Create;
  try
    for i := low(PDLLParams^) to high(PDLLParams^) do
        sl.Values[ inttostr(i) ] := FloatToStr( PDLLParams^[i] );

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

tieni conto che l'ho scritto di getto e non ho provato neanche a compilare, si tratta di darti un'idea

il fatto simon è che dal codice che scrivi appare chiaro che non hai acquisito le basi del pascal: usare una stringa come indice di un array o sperare che un array di extended abbia una proprietà che espone una istanza di TStrings vuol dire che probabilmente non è il momento di iniziare a scrivere codice complesso come quello che vuoi fare tu.
dovresti seguire il consiglio di legolas e stilgar e cioè apprendere le basi del pascal, IMHO le letture che ti ha consigilato legolas vanno più che bene ;)
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 02, 2013, 05:28:13 pm
Citazione
dovresti seguire il consiglio di legolas e stilgar

ASSOLUTAMENTE NO non seguo i consigli di Legols e Stilgar  poiché mi sono veramente antipatici non aiutano mai!!!!  scrivono poco codice e ti fanno sudare ;) ;) ;) ;) ;) ;D ;D ;D ;D

A parte gli scherzi, lo so che non ho le basi e sicuramente me le farò, ma ho fretta di fare questa benedetta dll poiché mi serve per terminare un progetto che ho fatto.
Quindi in qualche modo devo farla!!!
Mi sono già armato di libri tra un vostro aiuto e qualche lettura spero di tirare fuori qualcosa.
Vi saluto :)
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 02, 2013, 09:45:48 pm
Allora il problema sonoo solo queste righe, ho provato a commentarle e tutto ha funzionato ho tolto il commento e mi ha generato l'errore.
Se ruscite a darmi una mano su queste righe sono a cavallo ;)
Vi ringrazio

Codice: [Seleziona]

 if ApriSaveDialog.Execute then
    PInput^[Read].Lines.SaveToFile(ApriSaveDialog.Filename);


    if ApriOpenDialog.Execute then
    POutput^[Write].Lines.LoadFromFile(ApriOpenDialog.Filename);   

Inserisco tutto il codice:

Codice: [Seleziona]


library dialog;

{$mode objfpc}{$H+}

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

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]
  Read = 2;
  // I3 = 3;
  // ... I99 = 99;

  {OUTPUTS}// nome per numero di uscita
  Write = 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.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.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
      Read: Result := '$read';
    end;
  end;

  function OutputName(Channel: byte): ShortString; // trasferire nome di uscita
  begin
    case Channel of
      Write: Result := '$write'; // 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 CalculateEx(PInput,POutput,PUser: PDLLParams; PStrings: PStringParams); // Routine è permanente

  begin


    if PInput^[I0] > 2.5 then
      ApriOpenDialog;

    if PInput^[I1] > 2.5 then
      ApriSaveDialog;




    PInput^[Read] := Read;
    POutput^[Write] := Write ;




    if ApriSaveDialog.Execute then
    PInput^[Read];Lines.SaveToFile(ApriSaveDialog.Filename);


    if ApriOpenDialog.Execute then
    POutput^[Write];Lines.LoadFromFile(ApriOpenDialog.Filename);

  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 per salvare e richiamare file txt.
Inserito da: nomorelogic - Gennaio 02, 2013, 11:22:21 pm
farei così:

da qualche parte dichiara:
Codice: [Seleziona]
procedure SalvaArrayInFile(FileName: string);
var i:integer;
sl: TStringList;
begin
  sl := TStringList.Create;
  try
    for i := low(PDLLParams^) to high(PDLLParams^) do
        sl.Values[ inttostr(i) ] := FloatToStr( PDLLParams^[i] );

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



poi:
if ApriSaveDialog.Execute then
    PInput^[Read];Lines.SaveToFile(ApriSaveDialog.Filename);

dovrebbe diventare:
Codice: [Seleziona]
if ApriSaveDialog.Execute then
    SalvaArrayInFile(ApriSaveDialog.Filename);

poi dovresti fare qualcosa di simile per il load
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 02, 2013, 11:40:12 pm
Ciao nomorelogic
ecco gli errori che mi da adesso

Codice: [Seleziona]

project1.lpr(122,22) Hint: Parameter "PInput" not used
project1.lpr(122,30) Hint: Parameter "POutput" not used
project1.lpr(122,39) Hint: Parameter "PUser" not used
project1.lpr(136,46) Error: type identifier not allowed here
project1.lpr(166,23) Error: Illegal qualifier
project1.lpr(167,39) Error: Illegal qualifier
project1.lpr(222) Fatal: There were 3 errors compiling module, stopping


Le linea che mi da errore è questa:

Codice: [Seleziona]

sl.Values[IntToStr(i)] := FloatToStr(PDLLParams^[i]);

Poi queste:

Codice: [Seleziona]

    if ApriSaveDialog.Execute then
      SalvaArrayInFile(ApriSaveDialog.Filename)
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: nomorelogic - Gennaio 04, 2013, 03:11:16 pm
questa viene compilata e puoi testarla

Codice: [Seleziona]
library lib01;

{$mode objfpc}{$H+}

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

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]
  Read = 2;
  // I3 = 3;
  // ... I99 = 99;

  {OUTPUTS}// nome per numero di uscita
  Write = 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.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.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
      Read: Result := '$read';
    end;
  end;

  function OutputName(Channel: byte): ShortString; // trasferire nome di uscita
  begin
    case Channel of
      Write: Result := '$write'; // 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 := low(PAParams^) to high(PAParams^) do
          sl.Values[ inttostr(i) ] := 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
         // piuttosto che scrivere:
         // PAParams^[i] := StrToFloat(sl.Values[ inttostr(i) ]);
         // scrivendo come sotto è più facile fare il debug
         // quando l'hai testata puoi usare la forma commentata qui sopra
         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 s: shortstring;
  begin

    if PInput^[I0] > 2.5 then
      ApriOpenDialog;

    if PInput^[I1] > 2.5 then
      ApriSaveDialog;

    PInput^[Read] := Read;
    POutput^[Write] := Write ;

    s := ApriSaveDialog;
    if s <> '' then
       SalvaArrayInFile(s, POutput);

    s := ApriOpenDialog;
    if s <> '' then
       CaricaArrayDaFile(s, POutput);

  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 per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 04, 2013, 10:27:31 pm
Ciao nomore ti ringrazio molto, attualmente appena provo a mandare in esecuzione il programma(Profilab) le OpenDialog e SaveDialog si aprono da sole senza premere i pulsanti.

Ho aggiunto 2 variabili che mi serviranno per leggere e scrivere ma generano questo errore:

Codice: [Seleziona]

procedure CalculateEx(PInput, POutput, PUser: PDLLParams; PStrings: PStringParams);
  // Routine è permanente
  var
    s: shortstring;
     lettura:string;          // ho aggiunto queste variabili poichè mi serve leggere
     scrittura:string;         // ho aggiunto queste variabili poichè mi serve srivere
  begin

    if PInput^[I0] > 2.5 then
      ApriOpenDialog;

    if PInput^[I1] > 2.5 then
      ApriSaveDialog;

    PInput^[Leggi] := read(lettura);       //le due variabili le ho messe qui
    POutput^[Stampa] := write(scrittura);  //le due variabili le ho messe qui

    s := ApriSaveDialog;
    if s <> '' then
      SalvaArrayInFile(s, POutput);

    s := ApriOpenDialog;
    if s <> '' then
      CaricaArrayDaFile(s, POutput);

  end;                                                   


Codice: [Seleziona]

project1.lpr(122,22) Hint: Parameter "PInput" not used
project1.lpr(122,30) Hint: Parameter "POutput" not used
project1.lpr(122,39) Hint: Parameter "PUser" not used
project1.lpr(182,36) Error: Incompatible types: got "untyped" expected "Extended"
project1.lpr(183,40) Warning: Local variable "scrittura" does not seem to be initialized
project1.lpr(183,41) Error: Incompatible types: got "untyped" expected "Extended"
project1.lpr(218) Fatal: There were 2 errors compiling module, stopping



Ecco la dll completa:
Codice: [Seleziona]


library lib01;

{$mode objfpc}{$H+}

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

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.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.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 := low(PAParams^) to high(PAParams^) do
        sl.Values[IntToStr(i)] := 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
        // piuttosto che scrivere:
        // PAParams^[i] := StrToFloat(sl.Values[ inttostr(i) ]);
        // scrivendo come sotto è più facile fare il debug
        // quando l'hai testata puoi usare la forma commentata qui sopra
        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
    s: shortstring;
     lettura:string;          // ho aggiunto queste variabili poichè mi serve leggere
     scrittura:string;         // ho aggiunto queste variabili poichè mi serve srivere
  begin

    if PInput^[I0] > 2.5 then
      ApriOpenDialog;

    if PInput^[I1] > 2.5 then
      ApriSaveDialog;

    PInput^[Leggi] := read(lettura);       //le due variabili le ho messe qui
    POutput^[Stampa] := write(scrittura);  //le due variabili le ho messe qui

    s := ApriSaveDialog;
    if s <> '' then
      SalvaArrayInFile(s, POutput);

    s := ApriOpenDialog;
    if s <> '' then
      CaricaArrayDaFile(s, POutput);

  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.       

Ringrazio per l'attenzione
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Stilgar - Gennaio 05, 2013, 12:41:36 pm
Scusa, ma read e write sono quelle di sistema o le hai riscritte da qualche parte?
Non può andare in questo modo.
Se leggi un valore con read, essendo una procedura, cosa vuoi ottenere?
Che venga impostato il valore nelle varie celle dell'array?
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Legolas - Gennaio 05, 2013, 05:30:49 pm
Purtroppo continui a ignorare i suggerimenti che ti vengono dati e ad aggiungere comandi a casaccio...  :(
In questo modo, pur volendo, è davvero difficile poterti dare una mano, anche perché - e non è un rimprovero, ma una costatazione - parliamo linguaggi (di programmazione) differenti.

Ad esempio, ti avevo suggerito di aggiungere tutta la parte riguardante la configurazione nel comando Configure(), ma continui a metterla nel loop principale della dll.
Poi, spulciando tra i componenti di Profilab, ce ne sono alcuni che si occupano dell'input/output su file. Ho il sospetto che dovrai usare quelli per salvare e caricare valori. Ancora: c'è un componente che ti permette di salvare lo stato del front panel. Il componente Numeric Input accetta solo valori in uscita, quindi dalla dll non puoi impostarne il valore, ma soltanto utilizzando il componente di cui sopra.

Ciò detto, ho preparato un progettino di una semplice dll che accetta un input numerico e lo restituisce moltiplicato per un valore da impostare in una dialog di configurazione della dll. Vedi se riesci a tirarci fuori qualcosa di utile per il tuo progetto :)

Codice: [Seleziona]
Numeric Input --> DLL --> Numeric Display
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 05, 2013, 07:53:57 pm
Vi ringrazio per il supporto  :)
Forse mi spiego male piccola parentesi per Legolas( ho bisogno di chiamare le OpenDialog e SaveDialog da dei bottoni non posso configurare  e poi avviare l'applicazione, poi le numeric input sono uscite analogiche.Nel software non ce un modo per salvare su disco e poi richiamare il file salvato è per quello che mi sono ridotto a creare una DLL.
Quello che ho bisogno è di poter salvare su disco dei file txt tramite SaveDialog usando le numeric input, una volta salvate su disco devo poter richiamare il file txt con OpenDialog per poterlo caricare nelle numeric display ad ogni save con SaveDialog avrò tanti file txt dove poi potro scegliere cosa caricare con OpenDialog dentro le numeric display.

Ho inserito queste variabili appunto perché mi serve un modo per leggere nella variabile lettura quello che acquisisco da  ADD e la variabile scrittura per stampare nelle numeric display quello che leggo da i file txt aprendoli con OpenDialog.

Codice: [Seleziona]
    lettura: string;          // ho aggiunto queste variabili poichè mi serve leggere
    scrittura: string;         // ho aggiunto queste variabili poichè mi serve srivere


    PInput^[Leggi] := read(lettura);       //le due variabili le ho messe qui
    POutput^[Stampa] := write(scrittura);  //le due variabili le ho messe qui 


(http://i50.tinypic.com/2uptvo5.png)

Grazie per l'attenzione.
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: nomorelogic - Gennaio 05, 2013, 08:20:07 pm
simon75
le difficoltà che ci sono nell'apprendere un nuovo linguaggio di programmazione sono il pane quotidiano di tutti noi che in un modo o nell'altro diamo una mano in questo forum.
Però devi capire che il codice che tu scrivi, 2 righe alla volta, è costantemente un nonsense. Condito con le tue idee per aiutarci a capire cosa vuoi realizzare, ma di nonsense si tratta e per portarlo a termine hai bisogno di qualcuno che mastichi pascal.

Sei stato corretto all'inizio a specificare che non sei un programmatore pascal ma, per lavorare in questo modo, dovresti prima chiedere nel forum se c'è qualcuno che vuole partecipare al tuo progetto. Questo forum serve anche a questo, anzi, serve a questo e con questo si arricchisce.

Questo post non vuole essere un rimprovero ovviamente.
Devi però comprendere che non puoi darci le direttive per scrivere il tuo progetto. :)

Esempio di nonsense :) :
Codice: [Seleziona]
PInput^[Leggi] := read(lettura); 
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 06, 2013, 10:45:34 am
Ciao Legolas, cosa serve questo?

Codice: [Seleziona]
 {USER}
U0 = 0;
DLLIndex = 100;
Dove hai preso questa libreria?
Codice: [Seleziona]
Unit1 in 'Unit1.pas'; 
Puoi spiegarmi questo pezzo di codice?
Codice: [Seleziona]

  procedure Configure(PUser: PDLLParams);
  var
    DLG: TForm1;
  begin
    DLG := TForm1.Create(nil);
    with DLG do
    begin
      Caption := 'Counter [DLL' + FloatToStr(PUser^[DLLIndex]) + ']';

      if ShowModal = mrOk then
      begin
        puser^[U0] := SpinEdit1.Value;
      end;
      Free;
    end;
  end; 
Quel bottone che hai messo per moltiplicare i numeri come hai fatto a richiamarlo ovvero a renderlo visibile?

Ciao
Ti ringrazio
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Stilgar - Gennaio 06, 2013, 10:55:59 am
Simon,
 il progetto ha 2 "unità" logiche.
C'è il principale e una "form".
La form usa 2 file: "lfm" e "pas".
lfm contiene la definizioni e le risorse dei componenti grafici.
pas contiene il codice che usa il compilatore.

Il codice per il quale chiedevi spiegazioni è abbastanza semplice:
Codice: [Seleziona]

  procedure Configure(PUser: PDLLParams);
  var
    DLG: TForm1; // <- Definizione di una variabile di tipo TForm1
  begin
    DLG := TForm1.Create(nil); // <- Creazione dell'istanza della classe
    with DLG do // <- Serve a non ripettere di continuo DLG ad ogni utilzzo... come una sorta di scorciatoia
    begin
      Caption := 'Counter [DLL' + FloatToStr(PUser^[DLLIndex]) + ']'; //<- Assegna alla parte alta della finestra (caption) una stringa

      if ShowModal = mrOk then // <- Fa diventare MODALE la form. Rimane in primo piano (sull'applicazione)
      begin // <- Qui si entra solo se viene resituita OK dalla form di prima.
        puser^[U0] := SpinEdit1.Value;  // <- Assegna il valore del SpinEdit1 al PUser[U0].
      end;
      Free; Rilascia la ram dell'istanza usata
    end;
  end; 
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 06, 2013, 11:26:19 am
Grazie stilgar,


Per esempio potrei richimare qualsiasi oggetto? basta cambiare con TForm l'oggetto desiderato?

Codice: [Seleziona]
DLG: TForm1; // <- Definizione di una variabile di tipo TForm1


Ma che libreria prende questa?
Codice: [Seleziona]

Unit1 in 'Unit1.pas';



Questa è una costante perché l'ha messa in user?
Cosa serve metterla in user?
Perché 100?
Codice: [Seleziona]

DLLIndex = 100;

Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Stilgar - Gennaio 06, 2013, 01:34:04 pm
Le classi fanno da "tipo". Puoi dichiarare una variabile di qualsiasi tipo, ma se non sono tipi "base" li devi allocare e deallocare in memoria.

Unit1.pas è il file che contiene la form. (Lo zip non conteneva 200 file ... buttare un'occhiata?)

Perchè 100? Aspetta Legolas.
Gli indici validi, vanno da 0 a 100, ma potrebbe essere solo un caso. Se accedi ad un indice con PUser[101] vai a campi e leggi cose inconsistenti (Ammesso che non raggiri il compilatore, se non lo raggiri ti da errore e basta ;) )

Il fatto di scrivere cose PUser^[DLLIndex] non è "mettere" ma usare il valore.
L'assegnazione viene eseguita con l'operatore ":=", questo "mette" un valore dentro una variabile.
PUser^[DLLIndex] --> Leggi dell'array di puntatori a "extended" il centesimo valore.
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 06, 2013, 03:54:24 pm
Cavolo non ho fatto caso della Unit1 nella cartella :)

Ha dovuto scriverla Legolas, oppure l'ha composta con gli oggetti gia pronti di Lazarus?

Codice: [Seleziona]

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  Spin;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    Edit1: TEdit;
    Edit2: TEdit;
    OpenDialog1: TOpenDialog;
    SaveDialog1: TSaveDialog;
    SpinEdit1: TSpinEdit;
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.Button3Click(Sender: TObject);
begin
  if OpenDialog1.Execute then
    edit1.Text := OpenDialog1.FileName;
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
  if SaveDialog1.Execute then
    edit2.Text := SaveDialog1.FileName;
end;

initialization
  Application.Initialize;
end.

Saluti
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Legolas - Gennaio 06, 2013, 04:06:46 pm
Dllindex l'ho preso dalla documentazione di Profilab e dagli esempi:

Citazione
PUser^[0] to PUser^[99] can be used to store numeric user values. The values of these variables are saved in the ProfiLab project file, so that values are available agein, when the project is loaded next time. The variable PUser^[100] is set by ProfiLab and contains the number of the DLL component: 1 fo DLL1, 2 for DLL2, and so on.

La unit Unit1 l'ho fatta come si farebbe qualsiasi applicazione con lazarus: inserendo i componenti su un form e scrivendo il codice per gli eventi che mi occorrono :)
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 06, 2013, 05:37:28 pm
Legolas, quindi in 
Codice: [Seleziona]
procedure Configure(PUser: PDLLParams);
  hai richiamato la unit1 giusto?



Non potevi usare solo  Unit1 invece di
Codice: [Seleziona]
Unit1 in 'Unit1.pas';




Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Legolas - Gennaio 06, 2013, 05:57:32 pm
Legolas, quindi in 
Codice: [Seleziona]
procedure Configure(PUser: PDLLParams);
  hai richiamato la unit1 giusto?
Sì, esatto
Citazione
Non potevi usare solo  Unit1 invece di
Codice: [Seleziona]
Unit1 in 'Unit1.pas';

In questo caso sì, le due chiamate sono equivalenti. Se invece volessi aggiungere alla dll una unit presente in un'altra cartella, con "in" potrei specificare il percorso corretto. Ad esempio, se muovo unit1.pas e unit1.lfm nella cartella "units_della_dll", allora dovrei per forza scrivere:
 
Codice: delphi [Seleziona]
Unit1 in 'units_della_dll\Unit1.pas';
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: nomorelogic - Gennaio 07, 2013, 08:18:10 am
Ciao nomore ti ringrazio molto, attualmente appena provo a mandare in esecuzione il programma(Profilab) le OpenDialog e SaveDialog si aprono da sole senza premere i pulsanti.

In effetti avevo scritto una castroneria, prova così:
Codice: [Seleziona]
Procedure CalculateEx(PInput,POutput,PUser: PDLLParams; PStrings: PStringParams); // Routine è permanente
  var s: shortstring;
  begin

    if PInput^[I0] > 2.5 then
    begin
      s := ApriOpenDialog;
      if s <> '' then
         CaricaArrayDaFile(s, POutput);
    end;

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

    PInput^[Read] := Read;
    POutput^[Write] := Write ;

  end;

In questo modo i dialog dovrebbero aprirsi solo a comando.
Dovrebbe funzionare sia il salvataggio che il caricamento, facci sapere.
Ciao
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 07, 2013, 10:00:38 am
Ciao,
Adesso i dialoghi si aprono e si chiudono ( non esiste un sistema per bloccarli sulla schermata principale di profilab? perchè a volte mi scappano sul desktop).
Se inserisco un valore es. 234 nel numeri input e premo salva sulla finestra di dialogo esegue il save in maniera corretta, ma all'interno del file txt mi scrive questo: penso sia l'ARRAY :(
Invece se provo a caricare qualcosa da OpenDialog verso il display non non vedo niente.  :(
Vi saluto
0=0
1=0
2=0
3=0
4=0
5=0
6=0
7=0
8=0
9=0
10=0
11=0
12=0
13=0
14=0
15=0
16=0
17=0
18=0
19=0
20=0
21=0
22=0
23=0
24=0
25=0
26=0
27=0
28=0
29=0
30=0
31=0
32=0
33=0
34=0
35=0
36=0
37=0
38=0
39=0
40=0
41=0
42=0
43=0
44=0
45=0
46=0
47=0
48=0
49=0
50=0
51=0
52=0
53=0
54=0
55=0
56=0
57=0
58=0
59=0
60=0
61=0
62=0
63=0
64=0
65=0
66=0
67=0
68=0
69=0
70=0
71=0
72=0
73=0
74=0
75=0
76=0
77=0
78=0
79=0
80=0
81=0
82=0
83=0
84=0
85=0
86=0
87=0
88=0
89=0
90=0
91=0
92=0
93=0
94=0
95=0
96=0
97=0
98=0
99=0
100=0
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 07, 2013, 11:58:07 am
Stavo pensando, poi ditemi se sbaglio che attualmente sto sviluppando un programma windows (grafico) quindi non ho la console a carattere con cui deve funzionare una read o una write.
Quindi penso che la write e read non ha proprio senso.
Come posso far riconoscere la lettura e stampa se non posso usare tali comandi?
Saluti
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Stilgar - Gennaio 07, 2013, 12:06:03 pm
Ni.
Puoi riassegnare le variabili di output e input (handle di file di testo).
In questo modo puoi "virtualizzare" che sia un'applicazione consolle piuttosto che grafica.
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 07, 2013, 01:44:33 pm
Mi fai un esempio?
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Stilgar - Gennaio 07, 2013, 02:04:31 pm
Codice: [Seleziona]
Writeln(Output,'Testo di prova');
equivale a
Codice: [Seleziona]
Writeln('Testo di prova');
Se esegui prima un :
Codice: [Seleziona]
AssignFile(Output,'Filedioutput.txt');
Rewrite(Output);
fai grosso modo quello che per la console viene fatto per "puntare" all'output a video. Solo che fai il tutto su file.

Stessa cosa per il read. Al posto di averlo aperto su input standard (tastiera) puoi far leggere da file.

Stilgar
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 07, 2013, 02:45:27 pm
Ma Read e Write come sono adesso cosa sono? non mi sembrano variabili e quindi non posso scriverci dentro è anche per quello che non mi legge e ne stampa.

Codice: [Seleziona]

  procedure CalculateEx(PInput, POutput, PUser: PDLLParams; PStrings: PStringParams);
  // Routine è permanente

  var

    s: shortstring;




  begin

    if PInput^[I0] > 2.5 then
    begin
      s := ApriOpenDialog;
      if s <> '' then
        CaricaArrayDaFile(s, POutput);
    end;

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

    PInput^[Read] := Read;       
    POutput^[Write] := Write;   
  end;

Codice: [Seleziona]

    PInput^[Read] := Read;      //Questo ingresso Read cosa legge?
    POutput^[Write] := Write;   //Questa uscita write cosa stampa?


Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Stilgar - Gennaio 07, 2013, 02:51:31 pm
Codice: [Seleziona]
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]
  Read = 2;
  // I3 = 3;
  // ... I99 = 99;

  {OUTPUTS}// nome per numero di uscita
  Write = 0;  // valore Q0 = POutput[Q0] ossia POutput[0]
  //Q1 = 1;  // valore Q1 = POutput[Q1] ossia POutput[1]
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 07, 2013, 03:04:43 pm
infatti sono costanti che valgono una  Read = 2; Write = 0;
ecco perchè non funziona :o
Quindi dovrei dichiarare delle variabili per leggere e stampare ma le dichiaro come?
ho bisogno di leggere delle stringhe e stampare stringhe metterei

Codice: [Seleziona]
procedure CalculateEx......;
Var
Leggi : string;
Stampa : string;
begin
......
.......
.......
PInput^[Read] := read(Leggi) ;
POutput^[Write] := write(Stampa);
end;
Solo che mi darà problemi il compilatore e quindi dovrei convertirlo da stringa a extended potrei usare:

Codice: [Seleziona]
PInput^[Leggi] = StrToFloat(StringReplace(lettura,'.', ',', 
[rfReplaceAll]));


Non so ditemi voi  :)
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Stilgar - Gennaio 07, 2013, 03:20:38 pm
Dai che stai iniziando ad imboccare la strada giusta.
;)
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 07, 2013, 04:32:31 pm
Mi sa che ho bisogno di una controllatina  ??? :)

Codice: [Seleziona]

function StrToFloat ( FloatString : string ) : Extended;
  Var
  Leggi: string;
  Leggiuno:extended;
  Stampa: string;
  Stampauno:extended;
  begin
   Leggi:= PInput^[Read];
   leggiuno:=Leggi StrToFloat(Leggi);
   Stampa:=POutput^[Write];
   Stampauno:=Stampa StrToFloat(Stampa);
   end;

Codice: [Seleziona]

procedure CalculateEx............
.......
.......
......
......
.......


PInput^[Read] := readln(Leggi);
POutput^[Write] := writeln(Stampa);

  end;             


Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Stilgar - Gennaio 07, 2013, 04:43:45 pm
Codice: [Seleziona]
 begin
   Leggi:= PInput^[Read];
   leggiuno:=Leggi StrToFloat(Leggi);
   Stampa:=POutput^[Write];
   Stampauno:=Stampa StrToFloat(Stampa);
   end;
Osservazioni:
1) Ammesso che ti abbia compilato (e non credo), cosa volevi scrivere con
Codice: [Seleziona]
  leggiuno:=Leggi StrToFloat(Leggi);
Togli "Leggi" dopo ":=". Forse ti compila.
2) Ammesso che volessi scrivere
Codice: [Seleziona]
function StrToFloat ( FloatString : string ) : Extended;
begin
...
 leggiuno:=StrToFloat(Leggi);
Richiami la funzione dentro la funzione (ricosione) ma non vedo la condizione di uscita. Qui ti crepa lo stack di chiamata.

3) Leggi e scrivi... chi le valorizza?
Nessuno, per cui stai leggendo casualmente la memoria.

Codice: [Seleziona]
function StrToFloat ( FloatString : string ) : Extended;
  Var
  Leggi: string;
  Leggiuno:extended;
  Stampa: string;
  Stampauno:extended;
  begin
   Leggi:= PInput^[Read];
Ma se usi una funzione che legge una stringa e la traduce in numero, perchè non ti è venuto in mente di una stringa e tradurla in numero?

Non siamo in javascript che tutto fa brodo. ;)

Stilgar
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 07, 2013, 10:14:51 pm
Non riesco a capire come restituire il valore con le funzioni:

es:
Codice: [Seleziona]
function StrToFloat(Leggi, Stampa: string): extended;

  begin
    StrToFloat := StrToFloat(Stampa);
    StrToFloat := StrToFloat(Leggi);
  end;

Codice: [Seleziona]

procedure CalculateEx......
 var
    Leggi: extended;
    Stampa: extended;
begin
............
............
 
.........
..........
.........
 PInput^[Read] := readln(StrToFloat);
 POutput^[Write] := writeln(StrToFloat);
end;
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Stilgar - Gennaio 08, 2013, 03:09:29 am
http://www.freepascal.org/docs-html/ref/refse64.html#x118-12800012.2
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 09, 2013, 09:08:45 am
Helppppppppppp   :)




Codice: [Seleziona]

  procedure CalculateEx(PInput, POutput, PUser: PDLLParams; PStrings: PStringParams);
  // Routine è permanente

  var
    Leggi:string;
    Stampa:string;
    s: shortstring;

  begin



    if PInput^[I0] > 2.5 then
    begin
      s := ApriOpenDialog;
      if s <> '' then
        CaricaArrayDaFile(s, POutput);
    end;

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

    PInput^[Leggi] = StrToFloat(StringReplace(Leggi.Text,'.', ',',
    [rfReplaceAll]));
     POutput^[Stampa] = StrToFloat(StringReplace(Stampa.Text,'.', ',',
    [rfReplaceAll]));



  end;     

project1.lpr(129,22) Hint: Parameter "PInput" not used
project1.lpr(129,30) Hint: Parameter "POutput" not used
project1.lpr(129,39) Hint: Parameter "PUser" not used
project1.lpr(204,13) Warning: Local variable "Leggi" does not seem to be initialized
project1.lpr(204,18) Error: Incompatible types: got "AnsiString" expected "ShortInt"
project1.lpr(204,53) Error: Illegal qualifier
project1.lpr(205,21) Error: Illegal expression
project1.lpr(206,15) Warning: Local variable "Stampa" does not seem to be initialized
project1.lpr(206,21) Error: Incompatible types: got "AnsiString" expected "ShortInt"
project1.lpr(206,57) Error: Illegal qualifier
project1.lpr(207,21) Error: Illegal expression
project1.lpr(236) Fatal: There were 6 errors compiling module, stopping

Tutta la DLL
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 := low(PAParams^) to high(PAParams^) do
        sl.Values[IntToStr(i)] := 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
        // piuttosto che scrivere:
        // PAParams^[i] := StrToFloat(sl.Values[ inttostr(i) ]);
        // scrivendo come sotto è più facile fare il debug
        // quando l'hai testata puoi usare la forma commentata qui sopra
        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
    Leggi:string;
    Stampa:string;
    s: shortstring;

  begin



    if PInput^[I0] > 2.5 then
    begin
      s := ApriOpenDialog;
      if s <> '' then
        CaricaArrayDaFile(s, POutput);
    end;

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

    PInput^[Leggi] = StrToFloat(StringReplace(Leggi.Text,'.', ',',
    [rfReplaceAll]));
     POutput^[Stampa] = StrToFloat(StringReplace(Stampa.Text,'.', ',',
    [rfReplaceAll]));



  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 per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 09, 2013, 09:28:55 am
Codice: [Seleziona]

 procedure CalculateEx(PInput, POutput, PUser: PDLLParams; PStrings: PStringParams);
  // Routine è permanente

  var
    input:string;
    output:string;
    s: shortstring;

  begin



    if PInput^[I0] > 2.5 then
    begin
      s := ApriOpenDialog;
      if s <> '' then
        CaricaArrayDaFile(s, POutput);
    end;

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

    PInput^[Leggi] = StrToFloat(StringReplace(input.Text,'.', ',',
    [rfReplaceAll]));
     POutput^[Stampa] = StrToFloat(StringReplace(output.Text,'.', ',',
    [rfReplaceAll]));



  end;


project1.lpr(129,22) Hint: Parameter "PInput" not used
project1.lpr(129,30) Hint: Parameter "POutput" not used
project1.lpr(129,39) Hint: Parameter "PUser" not used
project1.lpr(204,53) Error: Illegal qualifier
project1.lpr(205,21) Error: Illegal expression
project1.lpr(206,57) Error: Illegal qualifier
project1.lpr(207,21) Error: Illegal expression
project1.lpr(236) Fatal: There were 4 errors compiling module, stopping
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Stilgar - Gennaio 09, 2013, 09:49:51 am
input.Text ???
output.Text ???
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 09, 2013, 09:55:42 am
Si perchè sto lavorando in ambiente grafico, non comandi per
ambiente a carattere (il vecchio MS DOS per intenderci).
Da una casella di testo c'è un solo
modo per Leggere il contenuto: es. Leggere.Text e per stampare Scrivere.Text:=Scrivere
Dovrebbe essere così...
Si ma ho degli errori :(

Codice: [Seleziona]

PInput^[Leggi] = StrToFloat(StringReplace(Leggere.Text,'.', ',',[rfReplaceAll]));
    POutput^[Stampa] = StrToFloat(StringReplace(Scrivere.Text:=Scrivere,'.', ',',[rfReplaceAll]));

project1.lpr(129,22) Hint: Parameter "PInput" not used
project1.lpr(129,30) Hint: Parameter "POutput" not used
project1.lpr(129,39) Hint: Parameter "PUser" not used
project1.lpr(207,55) Error: Illegal qualifier
project1.lpr(207,85) Error: Illegal expression
project1.lpr(208,58) Error: Illegal qualifier
project1.lpr(208,62) Fatal: Syntax error, ")" expected but ":=" found


Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Stilgar - Gennaio 09, 2013, 11:55:34 am
Codice: [Seleziona]
input:string; 
Codice: [Seleziona]
StringReplace(input.Text,'.', ',',

Non so dove tu veda il TEdit in queste dichiarazioni ... va bene usare le stringhe o i campi di edit ... ma nel modo corretto.

Qui usi il "confronto" come assegnazione.
Metti delle assegnazioni a caso ...
Codice: [Seleziona]
StringReplace(Scrivere.Text:=Scrivere
in
Codice: [Seleziona]
     POutput^[Stampa] = StrToFloat(StringReplace(Scrivere.Text:=Scrivere,'.', ',',[rfReplaceAll]));

Codice: [Seleziona]
 PInput^[Leggi] = StrToFloat
 POutput^[Stampa] = StrToFloat
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 09, 2013, 12:21:19 pm
Codice: [Seleziona]
var
    Leggere:Text;
    Scrivere:Text;

Avevo già provato a dichiararle come Text ma non cambiava nulla.

Devo configurare l'ingresso della dll per fa acquisire le stringhe che invio.
Stessa cosa per l'uscita, le deve inviare ai display da quelli salvati
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Stilgar - Gennaio 09, 2013, 01:02:24 pm
Simon, ribadisco il discorso già fatto.

Se io iniziassi a tartassarti con richieste sui BJT, senza sapere una mazza di elettronica, cosa mi consiglieresti?
Leggi qualche cosa e poi ne riparliamo.

Stai solo facendo confusione.
Da quello che stai scrivendo, mi viene da pensare che tu abbia una qualche esperienza con Javascript.
JavaScript è un linguaggio basato su direttive ECMA. Il concetto di "tipo" è molto aleatorio nei linguaggi ECMA.
In Pascal e altri linguaggi, il concetto di tipo è stringente.

Posso anche aprezzare i tuoi sforzi nel cercare di capire ed imparare, ma ti stai muovendo con una benda sugli occhi in un bosco. Per forza non ne esci.

Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 09, 2013, 01:41:02 pm
Citazione
Se io iniziassi a tartassarti con richieste sui BJT, senza sapere una mazza di elettronica, cosa mi consiglieresti?
Non ti farei girovagare nel bosco, ma ti darei la soluzione senza farti perdere altro tempo, da quella soluzione imparerai a non fare più errori senza farti scoraggiare.
Ti saluto
 :)
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 14, 2013, 09:13:51 am
I valori degli Array mi rimangono a zero, come posso fare?
Saluti
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Stilgar - Gennaio 14, 2013, 09:44:22 am
Vuol dire :
1) Leggi zeri
2) Non scrivi i valori correttamente
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: nomorelogic - Gennaio 14, 2013, 01:52:02 pm
infatti; per venirne a capo dovresti fare di test per capire come mai l'array non viene valorizzato.
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 14, 2013, 03:32:25 pm
Ciao,
Attualmente ho modificato cosi:
Codice: [Seleziona]


 procedure CalculateEx(PInput, POutput, PUser: PDLLParams; PStrings: PStringParams);
  // Routine è permanente

  var

    s: string;

  begin

    if PInput^[I0] > 2.5 then
    begin
      s := ApriOpenDialog;
      if s <> '' then
        CaricaArrayDaFile(s, POutput);
    end;

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

esattamente questa stringa:
Codice: [Seleziona]

SalvaArrayInFile(s, PInput);

In questo modo quello che scrivo nella tabella lo legge e fino a qui va bene ma in più mi scrive un 1=5 che non so dove lo pesca e in più tutto l'indice  del vettore da 1 a 100 cosa che non vorrei visualizzare.

0=0
1=5           questo da dove è uscito?
2=33434   questo numero l'ho scritto nella casella di testo OK
3=0
4=0
5=0
6=0
7=0
8=0
........n=100
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: nomorelogic - Gennaio 14, 2013, 03:37:08 pm
In questo modo quello che scrivo nella tabella lo legge e fino a qui va bene ma in più mi scrive un 1=5 che non so dove lo pesca e in più tutto l'indice  del vettore da 1 a 100 cosa che non vorrei visualizzare.

hai già verificato se nella posizione 1 c'è o no il valore 5?

per il resto che non vuoi visualizzare, basta che ci metti un if all'interno del loop, ad esempio:
Codice: [Seleziona]
for i := low(PDLLParams^) to high(PDLLParams^) do
    if PDLLParams^[i] <> 0 then
        sl.Values[ inttostr(i) ] := FloatToStr( PDLLParams^[i] );
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 14, 2013, 04:17:31 pm
Come faccio a verificarlo? l'elemento di posizione [] non cè.
attualmente nell'ingresso ho messo solo una casella quindi deve leggere solo un numero, però vorrei anche capire come fa a scegliersi lui l'indice del vettore per esempio in questo caso ha scritto nel 2=33434  e nel 1=5 questo l'ha generato da solo.

Codice: [Seleziona]

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

    sl := TStringList.Create;
    try
      for i := low(PAParams^) to high(PAParams^) do
        sl.Values[IntToStr(i)] := 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;
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Stilgar - Gennaio 14, 2013, 04:18:59 pm
Ma questo array è stato inizializzato a "0" prima di usarlo?
Così per sapere...
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: nomorelogic - Gennaio 14, 2013, 07:11:12 pm
in effetti inizializzare l'array non è una pessima idea ;)
comunque, fai una prova a salvare l'array appena creato
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 14, 2013, 11:53:31 pm
Ciao,
Non cambia nulla, ho provato a scrivere per esempio un "ciao", ma non  lo salva.
Pare che salva solo numeri sempre nel solito indice.

Codice: [Seleziona]

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


Codice: [Seleziona]

  procedure SalvaArrayInFile(FileName: string; PAParams: PDLLParams);
  var
    i: integer;
    sl: TStringList;
  begin
    i := 0;
    sl := TStringList.Create;
    try
      for i := low(PAParams^) to high(PAParams^) do
        sl.Values[IntToStr(i)] := 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
    i := 0;
    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;   





Ma se dovessi inserire PString dovrebbe risolvermi il problema? al posto di PInput e POutput?
Solo che dovrei modificare i 2 Array : CaricaArrayDaFile e SalvaArrayInFile


Codice: [Seleziona]

CaricaArrayDaFile(s, POutput);


 SalvaArrayInFile(s, PInput);




Codice: [Seleziona]


  procedure CalculateEx(PInput, POutput, PUser: PDLLParams; PStrings: PStringParams);
  // Routine è permanente

  var

    s: string;

  begin

    if PInput^[I0] > 2.5 then
    begin
      s := ApriOpenDialog;
      if s <> '' then
        CaricaArrayDaFile(s, POutput);
    end;

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

  end; 
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: nomorelogic - Gennaio 15, 2013, 09:01:04 am
Ciao,
Non cambia nulla, ho provato a scrivere per esempio un "ciao", ma non  lo salva.
Pare che salva solo numeri sempre nel solito indice.

scusa ma mi sono perso...
si tratta di un array di extended, dove lo hai scritto ciao?

Edit:
cambiando il tipo non è che risolvi più di tanto (a meno di un effetto collaterale fortunato) quindi il bug quasi sicuramente ti rimane.
Le due funzioni Salva e Carica sono piuttosto semplici, a occhio non penso sia lì il problema, cerca di capire come ci finisce quel valore nell'array.
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 15, 2013, 11:27:11 am
Allora in parte ha tolto tutto l'indice ma lascia solo 1=5 e 2=345 rimangono quelli dove va a scrivere ma vorrei togliere anche 1= e 2=
 :)

Codice: [Seleziona]
procedure SalvaArrayInFile(FileName: string; PAParams: PDLLParams);
  var
    i: integer;
    sl: TStringList;
  begin
    sl := TStringList.Create;
    try
      for i := low(PAParams^) to high(PAParams^) do

        if PAParams^[i] <> 0 then


          sl.Values[IntToStr(i)] := FloatToStr(PAParams^[i]);

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

Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: nomorelogic - Gennaio 15, 2013, 11:42:00 am
hai mica cercato "345" all'interno di tutto il sorgente?
mi viene il sospetto che ci sia qualche costante da qualche parte...
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 15, 2013, 11:46:46 am
345 è giusto l'ho scritto nella casella ti testo è solo il 5 che rompe ma sto cercando di capire se è il mio software che lo inserisce. come posso togliere 1= e 2= questi non vorrei vederli, dovrebbe rimanere solo per      es.  345
 :)
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: nomorelogic - Gennaio 15, 2013, 12:00:06 pm
se nel file non salvi l'indice poi come fai a ricaricarli nell'array alla giusta posizione?
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 15, 2013, 12:14:04 pm
Non posso salvare anche l'indice altrimenti quando andrò a caricarlo nel display mi visualizzerà anche l'indice assieme al valore  :)
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: nomorelogic - Gennaio 15, 2013, 12:30:19 pm
ma nel display ci metti i valori leggendo dall'array o no?

anche perchè l'altra funzione, quella che legge dal file, salva i valori nell'array...

inizio a pensare di non averci capito nulla  :-\


Edit:
comunque, nel caso, devi cambiare questa riga:
Codice: [Seleziona]
sl.Values[ inttostr(i) ] := FloatToStr( PDLLParams^[i] );

in questo modo:
Codice: [Seleziona]
sl.Add(FloatToStr( PDLLParams^[i] ));
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 15, 2013, 01:48:09 pm
:D Con OpenDialog Carico nel display i valori che ho salvato con SaveDialog.
Invece con SaveDialog salvo i valori per OpenDialog che una volta caricati li visualizza nel display  :)
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 15, 2013, 02:13:14 pm
 :)  nomore così salva benissimo ho solo quel 5 ma penso sia un problema del software che vedrò di togliere.... ;D
Ora mi rimane il problema che quando carico con OpenDialog nel display il file salvato da SaveDialog, il software mi genera un errore come se ci fosse un indirizzo sbagliato.
Bo devo verificare bene  :o
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 16, 2013, 03:08:21 pm
Ciao,
ho fatto varie prove è ho verificato che  nel momento che premo il pulsante per aprire il SaveDialog l'array acquisisce il valore 5 e lo stesso vale per l'OpenDialog.
Ora la mia domanda è : esiste un modo per evitare che l'array acquisisca questo valore 5 nel momento che premo il pulsante?
Vi ringrazio  :)


Codice: [Seleziona]

  procedure CalculateEx(PInput, POutput, PUser: PDLLParams; PStrings: PStringParams);
  // Routine è permanente

  var
    i: integer;
    sl: TStringList;
    s: string;

  begin

    if PInput^[I0] > 2 then
    begin
      s := ApriOpenDialog;
      if s <> '' then
        CaricaArrayDaFile(s, POutput);
    end;

    if PInput^[I1] > 2 then

    begin

      s := ApriSaveDialog;
      if s <> '' then
        SalvaArrayInFile(s, PInput);
    end;

  end;   



Codice: [Seleziona]


 procedure SalvaArrayInFile(FileName: string; PAParams: PDLLParams);
  var
    i: integer;
    sl: TStringList;
  begin
    sl := TStringList.Create;
    try
      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;
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: nomorelogic - Gennaio 16, 2013, 03:21:03 pm
lo sai usare il debugger?
quanto vale immediatamente prima del richiamo della funzione?
quanto vale appena entrati nel corpo della funzione?
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 16, 2013, 03:27:37 pm
No non so usarlo il debugger come si usa?
Sono sicuro che il problema arriva da li, anzi non è un problema è anche giusto che quando premo il pulsante mi generi il valore 5, ma vorrei dirgli di non scrivere il valore 5 nell'ARRAY nel momento che premo il pulsante. :)

Citazione
quanto vale immediatamente prima del richiamo della funzione?


Vale zero

Citazione

quanto vale appena entrati nel corpo della funzione?

Vale 5 ovvero pulsante premuto
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: nomorelogic - Gennaio 16, 2013, 03:49:11 pm
No non so usarlo il debugger come si usa?

Prima leggi qua per le impostazioni.
http://wiki.freepascal.org/Debugger_Setup (http://wiki.freepascal.org/Debugger_Setup)

Poi ti metti sulla riga dove vuoi interrompere l'esecuzione e poi schiacci F5: la riga diventa rossa e vuol dire che hai messo un breakpoint.
A questo punto vai sul menù esegui->parametri di esecuzione; inserisci il programma che usa la tua dll, confermi e lanci il tutto con F9.
Quando l'esecuzione arriva al breakpoint, l'esecuzione stessa dovrebbe interrompersi, torna l'IDE e puoi vedere come cambiano i valori (watches e local).
Con F7 / F8 puoi avanzare di una singola istruzione alla volta.


Se comunque col debugger vedi che il valore cambia ma non a causa del tuo codice, puoi forzare il valore 0 dentro all'array nel momento del salvataggio.

Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 16, 2013, 08:42:24 pm
Bella idea :) nomore...il problema è esterno, quindi puoi spiegarmi come forzare L'array a 0  :)
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: nomorelogic - Gennaio 17, 2013, 12:24:51 am
Bella idea :) nomore...il problema è esterno, quindi puoi spiegarmi come forzare L'array a 0  :)

CaricaArrayDaFile assegna dei valori all'array ;)
la sintassi la trovi già li
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Stilgar - Gennaio 17, 2013, 09:36:47 am
Ma se li hai salvati in testo questi dati, non puoi aggiustarli a mano e vedere se il problema si ripresenta?
Stilgar
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 18, 2013, 04:54:45 pm
Salve squadra Lazarus  :) ;)

Il 5 è stato affondato:)



Codice: [Seleziona]

procedure SalvaArrayInFile(FileName: string; PAParams: PDLLParams);
  var
    i: integer;
    sl: TStringList;
  begin
    sl := TStringList.Create;
    try
      for i := low(PAParams^) to high(PAParams^) do

        if i <> 5 then
          Write(i);

      if PAParams^[i] <> 0 then


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


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

Attualmente non riesco a leggere nel display quello che carico con OpenDialog, il tutto da quando ho tolto l'indice dell'array.
Per voi devo fare qualche modifica a:

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 := low(PAParams^) to high(PAParams^) do

      begin

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

      end;
    finally
      sl.Free;
    end;
  end;

Grazie ciao
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: nomorelogic - Gennaio 18, 2013, 05:03:59 pm
se carichi senza indice, carichi serialmente partendo dall'inizio...
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 19, 2013, 03:40:21 pm
Ciao a tutti,

Ho inserito come const a Leggi e Stampa questo  ''  ma ho dei problemi ti tipo nelle 2 funzioni.

project1.lpr(115,12) Error: Constant and CASE types do not match
project1.lpr(115,12) Error: Ordinal expression expected
project1.lpr(115,12) Error: duplicate case label
project1.lpr(122,13) Error: Constant and CASE types do not match
project1.lpr(122,13) Error: Ordinal expression expected
project1.lpr(242) Fatal: There were 5 errors compiling module, stopping

ciao

Codice: [Seleziona]

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 = 0;  // valore I1 = PInput[I1] ossia PInput[1]
  Leggi = '';
  // I3 = 3;
  // ... I99 = 99;

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


Codice: [Seleziona]


  function InputName(Channel: byte): ShortString; // trasferire nome di entrata
  begin
    case Channel of
      I0: Result := 'Cerca'; // nome di pin I0
      I1: Result := 'Salva'; // 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;   
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: nomorelogic - Gennaio 19, 2013, 03:54:36 pm
Ho inserito come const a Leggi e Stampa questo  ''  ma ho dei problemi ti tipo nelle 2 funzioni.

project1.lpr(115,12) Error: Constant and CASE types do not match
project1.lpr(115,12) Error: Ordinal expression expected
project1.lpr(115,12) Error: duplicate case label
project1.lpr(122,13) Error: Constant and CASE types do not match
project1.lpr(122,13) Error: Ordinal expression expected
project1.lpr(242) Fatal: There were 5 errors compiling module, stopping

In una istruzione CASE, come ti dice il comilatore, si possono usare solo tipi ordinali e le stringhe (Leggi e Stampa) non sono tipi ordinali.
Se devi per forza usare la stringa nulla devi sostituire il CASE con una serie di IF.

Altro errore: I0 e I1 sono si dei tipi ordinali (tutti i numeri interi lo sono) però hanno lo stesso valore e "duplicate case label" vuol dire che hai specificato due volte lo stesso valore in un CASE: non si può, un CASE può rispondere ad alternative mutuamente esclusive.
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 20, 2013, 12:16:55 am
nomore ho bisogno che mi aiuti a farlo, anche perché c'e una funzione di mezzo.
Codice: [Seleziona]

  function InputName(Channel: byte): ShortString; // trasferire nome di entrata
  begin
    case Channel of
      I0: Result := 'Cerca'; // nome di pin I0
      I1: Result := 'Salva'; // 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;

Non capisco che condizione devo dare, poi Result sarebbe il nome della funzione giusto?
function InputName(Channel: byte): ShortString;
if I0 = Result then 'Cerca' ;
if I1 = Result then 'Salva' ;
if Leggi = Result then '$Leggi';


function OutputName(Channel: byte): ShortString;
if Stampa = Result then '$Stampa';
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: nomorelogic - Gennaio 20, 2013, 10:25:55 am
Codice: [Seleziona]
  function InputName(Channel: byte): ShortString; // trasferire nome di entrata
  begin
    case Channel of
      I0: Result := 'Cerca'; // nome di pin I0
      I1: Result := 'Salva'; // nome di pin I1
      Leggi: Result := '$Leggi';
    end;
  end;

anche io ho bisogno di aiuto, non capisco che c'è da fare

insomma, togliendo il case dovresti scrivere:
Codice: [Seleziona]
// decommenta sotto nel caso Leggi sia un valore di default
// Result := '$Leggi';

if Channel = I0 then
   Result := 'Cerca';
if Channel = I1 then
   Result := 'Salva';

poi, da quello che hai scritto io capisco: "se Channel = Leggi".
Ma Leggi non è un canale, che ruolo ha allora?
Se è un valore di default decommenta come scritto sopra nel codice.

Il problema però non lo risolvi: la correzione sopra ti permette di compilare ma rimane il bug concettuale in quanto I0 e I1 hanno lo stesso valore (cioè 0) ==> sono lo stesso canale ==> la funzione (per Channel = 0) restituirà sempre e comunque "Salva".
Il "case" anche se non ti compila è giusto, il bug sta nel fatto che hai dichiarato questo:

Codice: [Seleziona]
const
 {INPUTS}// nome per numero di entrata
  I0 = 0;  // valore I0 = PInput[I0] ossia PInput[0]
  I1 = 0;  // valore I1 = PInput[I1] ossia PInput[1]

Probabilmente I0 e I1 devono avere valori diversi, o no?
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 20, 2013, 10:28:42 pm
Si Leggi è un canale d'ingresso, ma ho problemi di tipo perché ho messo come nullo la costante Leggi e Stampa  :)

project1.lpr(117,8) Error: Incompatible types: got "Byte" expected "AnsiString"
project1.lpr(128,8) Error: Incompatible types: got "Byte" expected "AnsiString"
project1.lpr(256) Fatal: There were 2 errors compiling module, stopping


Codice: [Seleziona]


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 = '';
  // I3 = 3;
  // ... I99 = 99;

  {OUTPUTS}// nome per numero di uscita
  Stampa = '';

Codice: [Seleziona]

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

Codice: [Seleziona]

function OutputName(Channel: byte): ShortString; // trasferire nome di uscita
  begin
    //case Channel of
    if Channel = Stampa then
      Result := '$Stampa';
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Stilgar - Gennaio 21, 2013, 09:49:16 am
STRINGHE
Codice: [Seleziona]
  Leggi = '';
  Stampa = '';

NUMERI
Codice: [Seleziona]
function OutputName(Channel: byte): ShortString; // trasferire nome di uscita

Codice: [Seleziona]
    if Channel = Stampa then

Che siano stringhe vuote o meno, il compilatore ti avvisa che stai confrontando tipo diversi e incompatibli.

Codice: [Seleziona]
  Leggi = $01;
  Stampa = '$02;

Con sto leggi e stampa stai facendo un casino pazzesco.
Inizia con dare nomi alle variabili che ti aiutino a capire cosa stai facendo.

Codice: [Seleziona]
  NomeDellPinLeggi = '';
  NomeDellPinStampa = '';

  NumeroDelPinLettura=$01;
  NumeroDelPinStampa=$02;

Sono gratis i caratteri, non hai problemi ad aggiungere linee di comunicazione tra le funzioni.

Stilgar
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Stilgar - Gennaio 21, 2013, 04:01:49 pm
Citazione
ho bisogno queste costanti nulle es: Leggi=''; Stampa='';
[/ (http://www.lazaruspascal.it/index.php?action=profile;u=691)quote (http://www.lazaruspascal.it/index.php?action=profile;u=691)] (http://www.lazaruspascal.it/index.php?action=profile;u=691)

Dipende.
1) non sono nulle,  ma vuote.
Nulle vuole dire 0x00, ma nel caso di stringa vuota, non è a 0x00.
2) Cosa ne devi fare?
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 21, 2013, 04:08:35 pm
Ho bisogno che Stampa sia vuoto, perchè nel momento che attivo il simulatore lui mi genera nel display il valore 0 che è la costante.
stessa cosa per Leggi che è l'ingresso lo vorrei vuoto. :)
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: nomorelogic - Gennaio 21, 2013, 06:49:08 pm
Codice: [Seleziona]

function OutputName(Channel: byte): ShortString; // trasferire nome di uscita
  begin
    //case Channel of
    if Channel = Stampa then
      Result := '$Stampa';

cerchiamo di capirci:

quando scrivi:
Codice: [Seleziona]
if Channel = Stampa then
è come se scrivi:
Codice: [Seleziona]
if 87 = 'ciao' then

l'unica cosa che puoi fare è "far finta" che il valore numerico -1 rappresenti la tua stringa nulla per cui potresti scrivere
Codice: [Seleziona]
if Channel = -1 then

Il problema è che ti stiamo dando consigli che nessuno di noi sa se sono contestualizzati con quello che devi fare...
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 22, 2013, 02:52:56 pm
Grazie Nomore e Stilgar vi ho stressato fin troppo, se Legolas puo farmi un piacere è meglio poichè ha provato il software.
Ciao Legolas hai tempo di provare la dll e verificare perchè non salva bene e non legge?
Ho allegato la parte di profilab manca da caricare la dll e provare. :)
Grazie

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 := low(PAParams^) to high(PAParams^) do
        if i <> 5 then
          Write(i);
      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
    i: integer;
    sl: TStringList;
    s: string;

  begin

    if PInput^[I0] > 2.5 then
    begin
      s := ApriOpenDialog;
      if s <> '' then
        CaricaArrayDaFile(s, POutput);
    end;

    if PInput^[I1] > 2.5 then

    begin

      s := ApriSaveDialog;
      if s <> '' then
        SalvaArrayInFile(s, PInput);
    end;

  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 per salvare e richiamare file txt.
Inserito da: Legolas - Gennaio 22, 2013, 03:27:57 pm
Ok, posso provare stasera, perché rientro tardi dal lavoro ;)
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Legolas - Gennaio 23, 2013, 03:54:05 pm
Allora, ho spulciato per benino il progettino e i sorgenti della dll. Mi incuriosiva il problema del 5 non voluto. Da dove viene? Nella dll abbiamo 3 canali di input e 1 di output. I canali di input sono così impiegati:

Canale 1 -> tasto salva
Canale 2 -> tasto carica
Canale 3 -> campo "Leggi"

Il canale di output invece è impiegato per la casella di testo "Stampa"

Nella procedura di salvataggio dell'array viene salvato lo stato dei 3 canali di input. Il 5 è lo stato di "premuto" del tasto di apertura della dialog.
Nella procedura di caricamento dell'array da file viene copiato il contenuto dei 3 canali di input sui canali di output. Siccome il primo canale di input (cioè lo stato del tasto che apre la dialog) è 5, allora il valore 5 viene copiato nel primo canale di output. Per questo motivo ti trovi quel 5 non voluto.

Soluzione? Trovare un sistema più consono per il salvataggio e il caricamento dei dati. Potresti ad esempio provare a salvare solo i canali che ti servono, sia input che output.


Devi anche fare in modo che le dialog non rimangano sempre aperte, cosa che adesso succede. Nell'esempio di dll in delphi c'è qualcosa a riguardo. Dovrebbe essere qualcosa di simile:

Codice: [Seleziona]
    
    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;
      PUser^[U0]:=PInput^[I0];

fermo restando che c'è da modificare CaricaArrayDaFile e SalvaArrayInFile
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 23, 2013, 09:41:38 pm
Ciao Legolas,

Citazione

Potresti ad esempio provare a salvare solo i canali che ti servono, sia input che output.


Come faccio a salvare solo i canali che mi servono?
Per salvare sono costretto a premere il Canale 1 -> tasto salva e di conseguenza mi salva il 5 perché esce un valore 5 da quel tasto.


Citazione

Devi anche fare in modo che le dialog non rimangano sempre aperte, cosa che adesso succede. Nell'esempio di dll in delphi c'è qualcosa a riguardo.

Si le dialog rimangono aperte perché il tasto rimane premuto se provi a ripremere il tasto si sblocca e poi si riesce a chiuderle, certamente non va bene così, spero di risolvere con quel codice che mi hai scritto.

Citazione

fermo restando che c'è da modificare CaricaArrayDaFile e SalvaArrayInFile

Non ho idea di come fare :o :)

Mi puoi spiegare questo : if (PInput^[I0] > 2.5) and not(PUser^[U0] > 2.5) then
il PUser cosa serve?
Grazie
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Legolas - Gennaio 23, 2013, 10:15:21 pm
Come faccio a salvare solo i canali che mi servono?
Per salvare sono costretto a premere il Canale 1 -> tasto salva e di conseguenza mi salva il 5 perché esce un valore 5 da quel tasto.

No, la conseguenza è che assegni il valore sbagliato al controllo sbagliato. Se il valore 5 lo salvi dal canale 1 degli input, perché poi lo assegni al canale 1 degli output?
Citazione
Citazione

fermo restando che c'è da modificare CaricaArrayDaFile e SalvaArrayInFile

Non ho idea di come fare :o :)

Semplice, invece di salvare tutto l'array, ti salvi soltanto i valori che ti servono, ad esempio il canale 3 degli input e il canale 1 dell'output. Così, quando li vai a rileggere, non devi fare altro che assegnare il primo valore alla casella di input e il secondo a quella di output

Citazione
Mi puoi spiegare questo : if (PInput^[I0] > 2.5) and not(PUser^[U0] > 2.5) then
il PUser cosa serve?
Grazie

PUser[U0] è una variabile di appoggio in cui viene inserito lo stato precedente del tasto, così sai se è già stato premuto e non riapre la dialog se non serve :)
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 24, 2013, 01:58:10 pm
Ciao Legolas,

Citazione
Se il valore 5 lo salvi dal canale 1 degli input, perché poi lo assegni al canale 1 degli output?


Mi puoi indicare dove lo sto assegnando?
dici qua? oppure devo modificare le costanti?
Codice: [Seleziona]

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;                                         


Citazione

invece di salvare tutto l'array, ti salvi soltanto i valori che ti servono, ad esempio il canale 3 degli input e il canale 1 dell'output.

Questa modifica la devo fare qui?

Codice: [Seleziona]
procedure SalvaArrayInFile(FileName: string; PAParams: PDLLParams);
  var
    i: integer;
    sl: TStringList;
  begin
    sl := TStringList.Create;
    try
      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;

Citazione

PUser[U0] è una variabile di appoggio in cui viene inserito lo stato precedente del tasto, così sai se è già stato premuto e non riapre la dialog se non serve

Attualmente si apre e si chiude bene, ma una volta aperto i dialog non posso più riaprili   :o

Ti ringrazio  :)

Ti allego tutta la dll che ho modificato

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 := 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
    i: integer;
    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;
      PUser^[U0] := PInput^[I0];

    end;



    if PInput^[I1] > 2.5 then

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

    end;

  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 per salvare e richiamare file txt.
Inserito da: Legolas - Gennaio 25, 2013, 06:32:01 pm
Citazione
Se il valore 5 lo salvi dal canale 1 degli input, perché poi lo assegni al canale 1 degli output?


Mi puoi indicare dove lo sto assegnando?
dici qua? oppure devo modificare le costanti?

Lo assegni in CaricaArrayDaFile. La funzione che salva l'array, spiego in parole povere, prende lo stato dei vari controlli DI INPUT (i due push button e il numeric input) e li salva su file in ordine:

riga 1 -> salva lo stato del push button 1
riga 2 -> salva lo stato del push button 2
riga 3 -> salva lo stato del numeric input
riga 4 -> 0
riga 5 -> 0
...
riga 99 -> 0
riga 100 -> 0

La funzione che carica i dati nell'array prende il file appena creato e lo carica nei controlli DI OUTPUT (in questo caso ce n'è solo uno, cioè il display):

riga 1 -> carica il valore di push button 1 in display
riga 2 -> carica il valore di push button 2, ma non viene utilizzato perché non ci sono altri controlli di output
riga 3 -> carica il valore di numeric input, ma non viene utilizzato perché non ci sono altri controlli di output
riga 4 -> carica il valore 0, ma non viene utilizzato perché non ci sono altri controlli di output
...
riga 99 -> carica il valore 0, ma non viene utilizzato perché non ci sono altri controlli di output
riga 100 -> carica il valore 0, ma non viene utilizzato perché non ci sono altri controlli di output

Citazione
Citazione

invece di salvare tutto l'array, ti salvi soltanto i valori che ti servono, ad esempio il canale 3 degli input e il canale 1 dell'output.

Questa modifica la devo fare qui?

Codice: [Seleziona]
procedure SalvaArrayInFile(FileName: string; PAParams: PDLLParams);
  var
    i: integer;
    sl: TStringList;
  begin
    sl := TStringList.Create;
    try
      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;

Esattamente. In questo caso ti salvi solo i due valori che ti servono e te li ricarichi assegnandoli ai controlli esatti

Citazione
Attualmente si apre e si chiude bene, ma una volta aperto i dialog non posso più riaprili   :o

In effetti c'è un piccolo "baco" nel codice che ti ho scritto (e un altro lo hai aggiunto tu). Prova così:

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;
        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^[U1] > 2.5) then
      begin
        s := ApriSaveDialog;
        if s <> '' then
          SalvaArrayInFile(s, PInput);
      end;
    end;
    PUser^[U1] := PInput^[I1];
  end;   

Tieni anche presente che i due button rimangono premuti perché il controllo passa alle dialog, quindi devi ripremerli una prima volta per "sbloccarli", dopodiché funzionano alla perfezione
Titolo: Re:DLL per salvare e richiamare file txt.
Inserito da: Simon75 - Gennaio 26, 2013, 11:06:07 am
Ciao, :)
Allora se voglio salvare solo l'ingresso 3 quindi (riga 3 -> salva lo stato del numeric input)
 dovrei fare cosi:

Codice: [Seleziona]

 for i := 3 to 3 do


Ma qunado salvo non vedo niente nel file di testo.

Ho provato così:

Codice: [Seleziona]

 for i := 0 to 3 do

e giustamente mi salva i tre ingressi e vedo il 5 e il numero che inserisco nella casella.

Per l'uscita ho fatto così:

Codice: [Seleziona]

for i := 0 to 1 do







Codice: [Seleziona]

 procedure SalvaArrayInFile(FileName: string; PAParams: PDLLParams);
  var
    i: integer;
    sl: TStringList;
  begin
    sl := TStringList.Create;
    try
      for i := 3 to 3 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 := 0 to 1 do

      begin

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

      end;
    finally
      sl.Free;
    end;
  end;


Legolas, c'è anche una cosa che non capisco:
Come mai appena abilito la simulazione in aiutomatico il display si setta a 0?
Dipende dalla costante $Stampa=0?
Ti Saluto