Solved

Defining a subset of an array

Posted on 2006-11-24
5
765 Views
Last Modified: 2012-06-22
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
//function DAQmxReadAnalogF64(taskHandle:Longint; numSampsPerChan:Longint; timeout:Double; fillMode:DAQmxFillMode;var readArray: Double; arraySizeInSamps:Longint; var sampsPerChanRead:Longint; reserved:Pointer):Longint; stdcall;
//"var readArray: Double;" is the variable in question

//Pass the address of element 0 of the array the contain all 40 data points
 ReadData(Data^[0]); //Actual declaration: ReadData(var Data : array of double);
//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
 ReadData(Data^[0]);
//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


0
Comment
Question by:cfm
5 Comments
 
LVL 28

Accepted Solution

by:
2266180 earned 250 total points
ID: 18006893
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
 
LVL 14

Expert Comment

by:Pierre Cornelius
ID: 18008610
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;


Let me know if you need more info.

Regards
Pierre
0
 
LVL 9

Expert Comment

by:alkisg
ID: 18009330
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 Comment

by:cfm
ID: 18025793
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
 
LVL 28

Expert Comment

by:2266180
ID: 18025814
I'm just curious: what wasn't good enough?
0

Featured Post

Efficient way to get backups off site to Azure

This user guide provides instructions on how to deploy and configure both a StoneFly Scale Out NAS Enterprise Cloud Drive virtual machine and Veeam Cloud Connect in the Microsoft Azure Cloud.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
add combobox item based on numbers 9 141
how to center only a line in richedit? 4 57
Intraweb download file link ? 1 133
Delphi and Access based Enumeration 9 63
The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
This Micro Tutorial hows how you can integrate  Mac OSX to a Windows Active Directory Domain. Apple has made it easy to allow users to bind their macs to a windows domain with relative ease. The following video show how to bind OSX Mavericks to …
A short tutorial showing how to set up an email signature in Outlook on the Web (previously known as OWA). For free email signatures designs, visit https://www.mail-signatures.com/articles/signature-templates/?sts=6651 If you want to manage em…

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question