Уважаемые профи, помогите, пожалуйста!
Мне необходимо передать массив n-ой длины в функцию, и соотв. вернуть массив возможно другой длины.
Кто знает какие способы, поделитесь, пожалуйста!!!Я в качеств предполагал использовать динамические массивы. Но как прочитал в
хелпе, функцией
SetLength можно задавать лишь массив длиной от 0 - 255, что не удовлетворяет. Хотя я пробовал выводить в
memo:
type
tArrayOfByte=array of byte;
var
arrb:^tArrayOfByte;
begin
new(arrb);
setlength(arrb^,999999);
memo1.lines.add(strtoint(length(arrb^)));
dispose(arrb); arrb:=nil;
Вроде бы все нормально проходило. Чему же верить?
Теперь остановился н с типом Pointer.
procedure TForm1.Button4Click(Sender: TObject);
{O-}
var
bb:pointer;
arrb:^tArrayOfByte;
bbsz,i:dword;
hmem:cardinal;
tmp:byte;
begin
bbsz:=128;
//=========Случайные данные для эксперимента==============
new(arrb);
setlength(arrb^,bbsz);
for i:=0 to bbsz-1 do begin
arrb^[i]:=random(255);
end;
//===============================================
hmem:=GlobalAlloc(GMEM_FIXED,bbsz);
bb:=GlobalLock(hmem);
CopyMemory(bb,arrb,bbsz);
NormalizeData8(bb,bbsz,128);
GlobalUnlock(GlobalHandle(bb));
GlobalFree(GlobalHandle(bb));
//dispose(arrb);
arrb:=nil;
end;
Процедура NormalizeData8 и 2 вспомогательные:
//перед вызовом, buff необходимо резервировать с пом. f GlobalAlloc, GlobalLock и освобождать соотв.
//NPoints- количество временных отметок для нормализации
function NormalizeData8(var buff:pointer; var buffsz:dword; NPoints:dword):integer;
var
RPoints,i,ind1,ind2,tmp: dword;
Knrr,ind: real;
buff2: pointer;
hmem: cardinal;
arrb: ^tArrayOfByte;
begin
result:=0;
if GlobalSize(GlobalHandle(buff))<buffsz then begin
ShowMessage('Ошибка: При вызове f NormalizeData8: неправильно инициализирован параметр buff');
result:=-1; exit;
end;
hmem:=GlobalAlloc(GMEM_FIXED,NPoints);
buff2:=GlobalLock(hmem);
for i:=0 to NPoints-1 do begin
SetByteToPtr(buff2,i,GetByteFromPtr(buff,i)); //для простоты, на самом деле происходит некое преобразование
end;
buffsz:=NPoints;
if GlobalUnlock(GlobalHandle(buff)) then GlobalFree(GlobalHandle(buff));
buff:=buff2; buff2:=nil;
end;
function GetByteFromPtr(p:pointer; ind:dword):byte;
var
pp:cardinal;
begin
if GlobalSize(GlobalHandle(p))<=ind then begin
ShowMessage('Ошибка: При вызове f GetByteFromPtr: индекс ('+inttostr(ind)+
') превышает размер выделенной памяти ('+inttostr(GlobalSize(GlobalHandle(p)))+')');
exit;
end;
asm
pusha
mov esi,dword ptr ind
mov edx,[p]
mov al,byte ptr [edx+esi]
mov byte ptr result,al
popa
end;
end;
function SetByteToPtr(p:pointer; ind:dword; val:byte):byte;
begin
if GlobalSize(GlobalHandle(p))<=ind then begin
ShowMessage('Ошибка: При вызове f SetByteToPtr: индекс ('+inttostr(ind)+
') превышает размер выделенной памяти ('+inttostr(GlobalSize(GlobalHandle(p)))+')');
exit;
end;
asm
pusha
mov esi,dword ptr ind
mov edx,[p]
mov al,byte ptr val
mov byte ptr [edx+esi],al
popa
end;
end;
В ассемблерных ф-ях из массива (т.е. указателя) берутся совсем не те числа, которые были туда скопированы. Подскажите, возможно я неправильно адресую память?
Или может есть другие способы работы с нетипизированными указателями для пересылки в подпрограммы динамических массивов данных.
Уже и не знаю, что придумать...