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
2
Medium Priority
?
583 Views
Last Modified: 2010-04-05
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
Comment
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
  • Learn & ask questions
2 Comments
 
LVL 26

Assisted Solution

by:Russell Libby
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

by:
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;
  memAddr : 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);
      value := INTARRAY(memAddr) ^;
      Form1.Memo1.Lines.Add(inttostr(value));
    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

Enroll in October's Free Course of the Month

Do you work with and analyze data? Enroll in October's Course of the Month for 7+ hours of SQL training, allowing you to quickly and efficiently store or retrieve data. It's free for Premium Members, Team Accounts, and Qualified Experts!

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

636 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