Delphi - chyba pri volani funkcie z DLL...
Mam tu dalsiu otazku z Delphi... v jednom programe pouzivam funkciu, ktora z retazca napr: "215 Sk" vytiahne cislo "215".
[pas]function GetNumber(s: string): real;
var i: byte;
sx: string;
begin
result:= 0;
sx:= '';
for i:= length(s) downto 1 do
if s[i] in['0'..'9', ','] then
sx:= s[i] + sx;
result:= StrToFloat(sx);
end;
[/pas]
Ak je tato funkcia v programe, je v vsetko v poriadku. Ale ked dam tuto funkciu do DLL kniznice a z programu volam tuto funkciu z DLL, tak prvy krat ide dobre. Ale druhy krat, ked ju pouzijem, tak vyhodi chybu: Access violation error...
[pas]function GetNumber(s: string): real; external cUtilsDLL;
[/pas]
cUtilsDLL = 'utils.dll' --> je to konstanta...
Preco to robi?
Problem je v tom, ze predavas string. Musis pouzit PCHar a velikost string alokovat.
Dalsi moznost je pouzit ShareMem.DLL a do uses pridat ShareMem (musi byt v Delphi i knihovne). Pak budes moct predavat stringy i Pascalovske objekty
Kolega Intex je mimo netu, tak som dostal úlohu zavolať mu, že aká je odpoveď. Mobil mu to to totiž neukázal celé.
Ale ak môžem poprosiť bližšie vysvetlenie prečo je to tak. Zaujíma to aj mňa aj Intexa. Dealokuje sa tam predávaný string alebo kde je vlastne problém? Ide o to, že ak budem vedieť prečo to tak je, tak v budúcnosti sa viem podobnému problému vyhnúť, ale ak nie, tak sa to môže s iným problémom zopakovať.
Čo tam upraviť poradňu na bezproblémové čítanie aj v mobiloch?
ANSI string neni vlastni retezec, ale jen odkaz na string. Takze do te knihovny byl predan pouze ukazatel a navic mechanismus DLL neumi primo s retezci pracovat.
Obvykle se predavani stringu pouzitim PChar + predanim jeho velikosti.
Takze to predani by mohlo vypadat takto:
[pas]var
s: string;
l: Integer;
Buffer: PChar;
begin
s := Meno1.Text;
l := Length(s);
Buffer := StrAlloc(l + 1);
StrPLCopy(Buffer, s, l);
// zde prijde volani funkce z DLL
StrDispose(Buffer);
end;[/pas]
v DLL se ziska string:
[pas]var
s: string;
begin
{ data: Pchar, DataSize: Integer jsou parametry DLL funkce }
SetString(s, Data, DataSize);
...
end;[/pas]
A čo sa po prvom volaní vlastne zmenilo, keď to až na druhýkrát nešlo?