Ciao Alka,
sono sempre in ballo con quella famosa DLL che sto sviluppando e ho scoperto che in qualche modo il puntatore utilizzato non si dealloca e alla seconda volta che richiamo la mia funzione, mi ritorna errore EInvalidPointer. Attualmente copio una stringa di tipo string in un puntatore e dalla funzione DLL passo il suo contenuto all'applicativo che ne fa richiesta. Pensavo di modificare la cosa in base ad un tuo suggerimento che mi avevi dato settimane fa, ovvero passare l'indirizzo del puntatore e non il suo contenuto.
Ho capito bene?

Non sono ancora in grado di sfruttare bene i puntatori, devo ancora comprenderli a pieno ma vorrei porre alla tua attenzione il codice utilizzato, sia per la DLL che per l'applicazione che la richiama. Magari sai dirmi dove effettivamente è sbagliato o magari mi puoi dare qualche altro suggerimento.

Funzioni residenti nella DLL (La funzione Polling() richiama la funzione DownloadPolling()):
codice:
Function DownloadPolling(IDBOX: Integer): String;
 var
  Response    : String;
  Content     : array of char;
  I           : Integer;

begin
  //Controllo che l'apertura sia stata correttamente eseguita
  if ApdComPort1.Open then
    begin
      //Invio il carattere EOT di chiusura per evitare trasmissioni aperte precedentemente
      ApdComPort1.PutString(chr($04));
      //Invio la stringa di Polling: [SOH][GID][DID][ENQ] che in esadecimale diventa [01][41][?][05]
      ApdComPort1.PutString(chr($01)+chr($41)+IntToStr(IDBOX)+chr($05));
      //Attivo il timer in modo da controllare il buffer per circa un secondo
      NewTimer(ET, 4);
      //Finchè il timer non si azzera controllo se il box mi ha spedito i dati
      I := 0;
      SetLength(Content, 104);
      Response := '';
      repeat
        while ApdComPort1.CharReady do
          begin
            Content[I] := ApdComPort1.GetChar;
            //if I > 5 then
              //begin
                //if I in [6..9] then Response := Response+IntToStr(Ord(Content[I]))
                //else Response := Response+Content[I];
              //end;
            I := I + 1;
          end;
      until TimerExpired(ET);
      for I := 1 to 104 do
        begin
          Response := Response+Content[I];
        end;
      Content := Nil;
      Result := Response;
    end
  else
    begin
      Result := '';
    end;
end;

Function Polling(DID: PChar): PChar; export; StdCall;
var
  ResponseBox : String;
  VerifyXor   : byte;
  I           : Integer;
begin
  if ApdComPort1 = nil then
    ApdComPort1 := TApdComPort.Create(nil);
  try
    //Configuro la porta seriale e la apro per iniziare le comunicazioni
    ApdComPort1.ComNumber := 1;
    ApdComPort1.Baud := 9600;
    ApdComPort1.Parity := pNone;
    ApdComPort1.DataBits := 8;
    ApdComPort1.StopBits := 1;
    ApdComPort1.InSize := 128;
    ApdComPort1.Open := true;
    FreeMem(Result, 105);
    if ApdComPort1.Open then
    begin
      //for N := 1 to Loop do
        //begin
          repeat
            //repeat
              ResponseBox := DownloadPolling(StrToInt(DID));
            //until ResponseBox <> '';
            VerifyXor := $00;
            if ResponseBox <> '' then
              begin
                for I := 1 to 104 do
                  begin
                    VerifyXor := VerifyXor xor Byte(ResponseBox[I]);
                  end;
                //Verifico l'esito del VCR, se 0 è corretto altrimenti c'è stato qualche errore
                if VerifyXor = 0 then
                  begin
                    //I dati sono corretti e invio la stringa di ritorno che il box si aspetta inviando un ACK = Hex(06)
                    ApdComPort1.PutString(Chr($01) + Chr($41) + Chr($31) + Chr($06));
                    //Chiudo la trasmissione con EOT
                    ApdComPort1.PutString(Chr($04));
                  end
                else
                  begin
                    //I dati sono errati e invio la stringa di ritorno che il box si aspetta inviando un NACK = Hex(15)
                    ApdComPort1.PutString(Chr($01) + Chr($41) + Chr($31) + Chr($15));
                    //Chiudo la trasmissione con EOT
                    ApdComPort1.PutString(Chr($04));
                  end;
              end
            else
              begin
                ResponseBox := 'ERROR';
              end;
          until VerifyXor = 0;
        //end;
      //Chiudo la porta di comunicazione
      ApdComPort1.Open := false;
      end
    else
      begin
        ResponseBox := 'COM Port Close';
      end;
    //Alloco memoria per contenere il valore di ritorno della funzione da passare al software
    GetMem(Result,105);
    //Copio il valore di ritorno nella variabile che la funzione ritorna
    Result := StrPCopy(Result, ResponseBox);
  finally
    ApdComPort1.Free;
  end;
end;
Questo è il codice dell'applicazione
codice:
TextReturn := Polling('1');
        //Alloco memoria per contenere il valore di ritorno della funzione da passare al software
        GetMem(Return,Length(TextReturn)+1);
        //Copio il valore di ritorno nella variabile che la funzione ritorna
        Return := StrPCopy(Return, TextReturn);
        Memo1.Lines.Add(Return);
        FreeMem(TextReturn, Length(TextReturn)+1)
Mi viene un dubbio, se io passo l'indirizzo del puntatore dalla DLL all'applicazione, posso copiare il suo contenuto in una stringa per poi deallocare la memoria del puntatore senza perdere i dati copiati?

Grazie