Author: Tomas Rutkauskas
How to pass multidimensional arrays as parameters to a function or procedure
Answer:
Passing an array to a procedure or function is straight forward and behaves as
expected. However, passing a multi-dimensional array to a function or procedure is
not handled in the same way. Consider MyArray to be defined as:
1 var2 MyArray: array[1..3, 1..5] of double;
3 4 5 //And you want to pass it to a procedure called DoSomeThing() defined as:6 7 8 procedure DoSomeThing(MyArray: arrayof double);
9 begin10 showmessage(floattostr(MyArray[1, 1]));
11 end;
One might think a simple statement like DoSomeThing(MyArray); would do the trick.
Unfortunately, this is not the case. The statement DoSomeThing(MyArray); will not
compile. The compiler sees the two data structures involved as different types - so
it will not allow the statement. The DoSomeThing() procedure is expecting an array
of doubles, but the example is passing a multi-dimensional array.
Delphi handles multi-dimensional arrays as user defined type, so there is no syntax
to tell a procedure that its parameter(s) are multi-dimensional arrays - without
declaring a type. Creating a type, and using this type as the parameter is the
correct method to pass a multi-dimensional array. We could just pass a pointer to
the array, but inside the function, we need to typecast that pointer. What type to
cast it as is the next issue. You would have to have the type defined, or declared
identically in 2 places. This method just doesn't make sense.
By defining a type, we can change the process to this:
12 type13 TMyArray = array[1..3, 1..5] of double;
14 15 var16 MyArray: TMyArray;
17 18 procedure DoSomeThing(MyArray: TMyArray);
19 begin20 showmessage(floattostr(MyArray[1, 1]));
21 end;
22 23 //Now the actual call looks as we expected:24 25 DoSomeThing(MyArray);
If you want to use the method of passing a pointer, your function might look like
this:
26 type27 PMyArray = ^TMyArray;
28 TMyArray = array[1..3, 1..5] of double;
29 30 var31 MyArray: TMyArray;
32 33 procedure DoSomeThing(MyArray: PMyArray);
34 begin35 showmessage(floattostr((MyArray[2, 3])));
36 end;
Note, under 32 bit version Delphi, you do not need to dereference the MyArray
variable inside DoSomeThing(). Under older versions you might have to refer to
MyArray as MyArray^.
If you want to pass just a generic pointer, you may not be able to use it directly.
You can declare a local variable, and use it. Again, you may need to cast the local
variable for older versions of PASCAL. Of course this method does offer more
flexibility in data usage.
37 procedure DoSomeThing(MyArray: pointer);
38 var39 t: ^TMyArray;
40 begin41 t := MyArray;
42 ShowMessage(FloatToStr(t[2, 3]));
43 end;
Regardless, both calls that use a pointer method, will look something like:
44 MyArray[2, 3] := 5.6;
45 DoSomeThing(@MyArray);