Newsgroup: it.comp.lang.delphi
Titolo: [DLL] Dubbio sui valori di ritorno e rilascio della memoria

Ho scritto in delphi alcune dll che devono essere utilizzate
da altri ambienti (acces, word,excel e FoxPro e forse VB)
Ad un certo punto mi sorgono alcuni dubbi sul rilascio della
memoria....
In questo codice e il proramma chiamante che si preoccupa di liberare
la memoria.... ?
function TagliaPrimoCarattere( s:Pchar):Pchar; stdcall;
var 
ptr:Pchar;
len:cardinal;
begin //qui non sto a testare null o empty
	ptr:=S+1;
	len:=strlen(s); 
	GetMem(result,len);
       	StrCopy(Result,ptr);	
end;
 
Sarà il programma chiamante a liberare la memoria o mi rimane
occupata?
e se io faccio questa operazione pericolosa ? cosa succede...
function TagliaPrimoCarattere( S:Pchar):Pchar; stdcall;
var 
begin //qui non sto a testare null o empty
	result:=S+1;
end;
Assegno a result un pericloso puntatore alla stessa variabile S
Dalle prove che o fatto mi sembra non ci siano problemi....
se io chiamo la func
A='abcd'
B=TagliaPrimoCarattere( A)
B='123'
non è che mi ritrovo in A il valore a123
Ho fatto alcune prove che mi hanno dato risposte empiriche, ma vorrei
un chiarimento sul modo e i mecchanismi in cui vengono gestiti questi
scambi di dati.

Nel modo in cui l'hai descritta quello che succede č che fai puntare il
valore di sitorno a quello di partenza +1.
Questo non garantisce affatto che la memoria venga liberata (ne da DLL
ne da applicazione Host).
tutt'al + potresti fare allocare la memoria a partire dal valore di
ritorno subito dopo aver deallocato la prima.
Solo cosě hai la garanzia che qulla locazione di memoria viene liberata.
Il mio consiglio č comunque quello di far deallocare la memoria dalla
DLL e non dall'applicazione host, ma solo per una questione di eleganza.
poi potresti tutt'al + lasciare la versione che non dealloca la memoria
se t serve riutilizzare la stringa "di partenza".
CMQ la DLL deve essere vista come parte dell'applicazione e dunque non
fa differenza che faccia parte o meno dall'app host.
Saluti Jano Crimi!
-- 
Posted via Mailgate.ORG Server - 
http://www.Mailgate.ORG

ne da applicazione Host).
Intanto grazie per la risposta...
Questo che dici è la seconda delle due versioni dello stesso programma
di esempio. Nel primo infatti è la dll ad allocare la memoria.
Il secondo è una prova tecnica. Quello che mi stupisce è che sembra
funzionare. Io in realtà mi aspettavo dei problemi, magari un errore a
livello di sistema, ma quando ritorno nel programma chiamante sembra
che le due variabili abbiano corso indipendente....
La prova l'ho effettuata con Visualfox
Posto di nuovo le righe di codice per capirci...
---- Pascal
function __test(S: pchar): Pchar; stdcall;
begin //qui non sto a testare null o empty
	result:=S+1;
end;
--------
Chiamata da fox (? = print del basic)
declare	string __test in "mialib.dll" as test string @w_str
a="ABCD"
b=test(a)
?b  ---- stampa giustamente "BCD"
b="123"
?a ---- stampa ancora "ABCD" e non come mi aspettavo "A123"
Mi andrebbe benissimo, ma mi lascia perplesso.
Vedo 2 possibili spiegazioni per questo fenomeno...
1) La prima che il programma chiamante copia (arrivando fino a primo
carattere di termine #0? ) il valore di ritorno dentro la sua
variabile. Questo renderebbe un inutile spreco di cicli macchina fare
il  GetMem(result,len+1); e il  StrCopy(Result,S);
all'interno della DLL
2) La seconda spiegazione (più probabile) è che quando in foxpro
assegno un nuovo valore alla variabile B,  venga creato un nuovo
puntatore a una nuova area di memoria completamente indipendente dal
primo e in questo caso sarebbe interessante sapere se il resto della
stringa BCD viene considerato, pericolosamente, memoria libera al
momento della riallocazione di B. In questo caso comunque affidarsi a
a questa proprietà sarebbe un errore e l'allocazione dello spazio
all'interno della dll sarebbe necessario, perchè anche ammesso che per
Fox funzioni bene, la cosa non sarebbe portabile.
Adesso per togliermi il dubbio e sapere se posso fare l'ottimizzazione
farò la prova chiamando la dll da un programma delphi. Qui posso
vedere i  puntatori e quindi posso realmente controllare come si
comporta. Avrei dovuto farlo subito, ma il dubbio si è sviluppato per 
gradi mentre ci ragionavo.

farň la prova chiamando la dll da un programma delphi.
Ho fatto le prove e contrariamente a vfp delphi a fatto quello che mi
aspettavo senza farmi venire strani dubbi.
dopo queste istruzioni
   getmem(a,10);
   strcopy(a,'abcde');
   b:=test(a);
   b^:='1';
ottengo a='a1cde'
In effatti al ritorno della funzione b contiene un puntatore ad a+1 e
non una copia dei dati (come mi era sembrato in un primo momento
testando la dll con vfp)
ok vada per la soluzione del tipo
    len:=strlen(S);
    GetMem(result,len+1);
    StrCopy(Result,S+1);