# Defining a subset of an array

Hi, need to pass an array to a C compiled ddl, read the returned array and break it up into 4 smaller arrays.

The array I want to read back, is one long array, containing 4 sets of smaller arrays. I want to assign the address of the first element of each subset of data to a variable (of type array) so that I have 4 smaller arrays.

Consider the sample code:

const
Samples = 10;
type
TArray = array of Double;
var
Data, Data0, Data1, Data2, Data3: ^TArray;
begin
SetLength(Data^, 4*Samples);

//The actual Delphi call to the C DLL
//"var readArray: Double;" is the variable in question

//Pass the address of element 0 of the array the contain all 40 data points
//Set the address of Data0, the fisrt 10 data points
Data0 := Data;
SetLength(Data0^, Samples);

//Set the address of Data1, the second 10 data points
Data1 := Data^[10];
SetLength(Data1^, Samples);

//Set the address of Data2, the third 10 data points
Data2 := Data^[20];
SetLength(Data2^, Samples);

//Set the address of Data3, the forth 10 data points
Data3 := Data^[30];
SetLength(Data3^, Samples);
end;//The code above does not work in practise, but I'd it to be implemented in a simular manner

//This is how I can get it to work
const
Samples = 10;
type
TArray = array of Double;
var
Data, Data0, Data1, Data2, Data3: TArray;
n: integer;
begin
SetLength(Data^, 4*Samples);

//Pass the address of element 0 of the array the contain all 40 data points
//Set the address of Data0, the fisrt 10 data points
Data0 := Data;
SetLength(Data0^, Samples);

SetLength(Data1^, Samples);
SetLength(Data2^, Samples);
SetLength(Data3^, Samples);

for n := 0 to 9 do
begin
Data1^[n] := Data^[n+10];
Data2^[n] := Data^[n+20];
Data3^[n] := Data^[n+30];
end;
end;

This is a problem as I need to process up to 5E6 for each data set

###### Who is Participating?

Commented:
you won't be able to do that with just dynamic arrays since they are not just a series of elements in the memory. there is otehr information saved as well.

shortly:
- the data starts at @a[0]
- the data about teh array (length, element size?, etc) is stored at @a
- if you get the address of element X from the array, you still need a valid address for the dynamic array itself in order to cast and successfully use.

the workaround is to use static arrays. small example:

procedure TForm1.FormCreate(Sender: TObject);
type TElement=integer;
PArray=^Tarray;
TArray=array [0..30000] of TElement;
var a:TArray;
i:integer;
s:array[1..4] of PArray;
ss:string;
l:integer;
begin
l:=16;
for i:=1 to l do// initialize some test data
a[i-1]:=i;
for i:=1 to 4 do// initialize the subsets
s[i]:=pointer(integer(@a[0])+(i-1)*(l div 4){the number of elements in the subset}*sizeof(TElement){the length of the type of the elements});
ss:='';
for i:=1 to 4 do// show the first element of each subset
ss:=ss+inttostr(s[i]^[0])+' ';
showmessage(ss);
end;
0

Commented:
It seems your returned array is of fixed length i.e. 40 bytes and you want to reference it as 4 separate arrays each of 10 bytes. If my understanding is correct, then you simply need to use a multidimensional array to reference the data accordingly. Something like this:

var
Data: array[1..4, 1..10] of double;
begin
after your call to DAQmxReadAnalogF64 the Data variable can be referenced as follows:
Data[1,1] = data set 1 point 1
Data[1,2] = data set 1 point 2
Data[2,1] = data set 2 point 1
Data[3,1] = data set 3 point 1
etc.

another option is to structure the data something like this:

type
TDataPoints = array[1..10] of double;
TDataPointsSet = array[1..4] of TDatapoints;

Regards
Pierre
0

Commented:
IF Samples is constant, you may also use a record:

const
Samples = 10;
type
MyArray = packed record
case byte of
0: (a: array[1..4*Samples] of integer);
1: (b, c, d, e: array [1..Samples of integer);
end;

In this case, record.a overlaps with record.b, record.c, record.d and record.e so it does what you want with an easier syntax:
with record do
begin
a[1] := ...
b[1] := ...
end;

I like the other (Ciuly's and Pierre's) ideas better, though! :-)
0

Author Commented:
PierreC and alkisq

Did try playing with multidimensional arrays and records earlier.  Ran into trouble getting the variable accepted by the function in the dll.
0

Commented:
I'm just curious: what wasn't good enough?
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.