Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
Solved

C Multidimensional arrays and Delphi

Posted on 2004-10-27
Medium Priority
583 Views
How can I pass a Delphi Multidimensional array to a C function that has the following declaration?

int Teste(int **v, int l, int c)

I know that Delphi and C have different Multidimensional arrays memory organizations. But I could not find any resource explaining clearly how can I bypass that.

Thanks
Mauricio.

0
Question by:MauricioMaia
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

• Help others & share knowledge
• Earn cash & points

LVL 26

Assisted Solution

Russell Libby earned 500 total points
ID: 12426475
Mauricio,

The following will allow you to allocate a 2 dimensional integer array that can be passed to the C function. You didn't specifiy the number of dimensions, but looking at the Tests function, I made the assumtion that it was 2.

// The declaration
//
// type declarator [<constant-expression>]
//
// declares an array composed of elements of type. An array consists of a
// contiguous region of storage exactly large enough to hold all of its elements.
// If an expression is given in an array declarator, it must evaluate to a
// positive constant integer. The value is the number of elements in the
// array. Each of the elements of an array is numbered from 0 through the
// number of elements minus one.
//
// Multidimensional arrays are constructed by declaring arrays of array type.
//

type
IntegerArray      =  Array [0..Pred(MaxInt shr 4)] of Integer;
PIntegerArray     =  ^IntegerArray;
TMDIntegerArray   =  Array [0..Pred(MaxInt shr 4)] of PIntegerArray;
PMDIntegerArray   =  ^TMDIntegerArray;

function CreateMDIntArray(Rows, Cols: Integer): PMDIntegerArray;
var  dwIndex:    Integer;
begin

// We will allocate one more row than required (AND leave it null). This will
// allow us to free the array without knowing the actual number of rows
result:=AllocMem(Succ(Rows) * SizeOf(PIntegerArray));

// Allocate memory for each row (except the last)
for dwIndex:=0 to Pred(Rows) do result^[dwIndex]:=AllocMem(Cols * SizeOf(Integer));

end;

procedure FreeMDIntArray(MDIntArray: PMDIntegerArray);
var  dwIndex:    Integer;
begin

// Set starting index
dwIndex:=0;

// Walk the rows until null is reached
while Assigned(MDIntArray^[dwIndex]) do
begin
FreeMem(MDIntArray^[dwIndex]);
Inc(dwIndex);
end;

// Free the array
FreeMem(MDIntArray);

end;

var  pmdaTest:      PMDIntegerArray;
begin

// Create the multidimensional array
pmdaTest:=CreateMDIntArray(10, 5);

// Set [5, 0] to = 100
pmdaTest^[5]^[0]:=100;

// Pass the array to the teste function (used 5 and 0 for the other params, just for example)
Teste(pmdaTest, 5, 0);

// Free the array
FreeMDIntArray(pmdaTest);

end;

---

Hope this helps,
Russell

0

Accepted Solution

Metrix_ earned 500 total points
ID: 12429571
Delphi

Static array types
A static array is stored as a contiguous sequence of variables of the component type of the array. The components with the lowest indexes are stored at the lowest memory addresses. A multidimensional array is stored with the rightmost dimension increasing first.
(Ref: http://info.borland.com/techpubs/delphi/delphi5/oplg/memory.html)

ANSI C (and C++ i believ)

Multidimensional Arrays
Multidimensional arrays are simply arrays of arrays (of arrays of arrays...)
A multidimensional array like m[3][2] is stored in consecutive memory locations as m[0][0], m[0][1], m[1][0], m[1][1], m[2][0], m[2][1]

So if you are using a Static interger array you should simply be able to pass the delphi array into the C function by typecasting the array to a pointer.

NOTE: In C teh int **V is just a pointer to a memory location, which is the first integer in the array

Here is some sample delphi code with a C like function i wrote to test this

type
INTARRAY = ^integer;   // int *
PINTARRAY = ^INTARRAY; // int **

// Test function to simulate a C style multidimesional integer array
// int Teste(int **v, int l, int c)
function Teste(v : PINTARRAY; cols : integer; rows : integer) : integer; stdcall;
var
idxC, idxR : integer;
value : integer;
begin
for idxR := 0 to Rows - 1 do
for idxC := 0 to Cols - 1 do
begin
//start + (y * width) + x;      width := sizeof(integer) * x)
memAddr := integer(v) + (idxR * (sizeof(integer) * cols)) + (idxC * 4);
end;

result := 0;
end;

procedure TForm1.Button2Click(Sender: TObject);
const
COLCOUNT = 10;
ROWCOUNT = 5;
var
col : integer;
row : integer;
aryDelphi : array[0..COLCOUNT - 1,0..ROWCOUNT - 1] of integer; // [cols, rows]
begin

//Fill in the array values
for row := 0 to 4 do
begin
for col := 0 to 9 do
begin
aryDelphi[col][row] := (col * 5) + row;
end;
end;

//I have assumed the Teste function will loop through the array using l and c
// as the cols and orws value, in this case 10 columns by 5 rows
Teste(@aryDelphi, COLCOUNT, ROWCOUNT);
end;

Hope it helps

Richard Owen
0

Featured Post

Question has a verified solution.

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

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
In this video, Percona Solution Engineer Dimitri Vanoverbeke discusses why you want to use at least three nodes in a database cluster. To discuss how Percona Consulting can help with your design and architecture needs for your database and infras…
Want to learn how to record your desktop screen without having to use an outside camera. Click on this video and learn how to use the cool google extension called "Screencastify"! Step 1: Open a new google tab Step 2: Go to the left hand upper corn…
Suggested Courses
Course of the Month11 days, 15 hours left to enroll