Question

I am trying to call a procedure in a Delphi DLL from C#. The procedure expects the caller to preallocate and input an array of array of TSomeRecord, of which it will then manipulate the TSomeRecord elements as a means of returning results. So, I need to hand-craft Delphi dynamic arrays of arrays of X.
Now, I have found here that a dynamic array of X consists of a pointer to the first element of the dynamic array, and that that first element has a reference count and the length (number of elements) of the array prepended (both 32-bit integers), and that the elements are stored inline and contiguously, so that the whole thing looks like this in memory:

rrrrllll000...000111...12...
        ^

with rrrr the reference count, llll the length, 0123 the elements, and ^ where the pointer points to. This bears out; I have tested it and it works.
For multidimensional dynamic arrays I have assumed that I can substitute array of Y for the X in array of X, in other words that the outer dimension is simply a dynamic array of (pointers to) dynamic arrays, like so:

rrrrllll000011112222...
        ^

where the elements 0000, 1111 etc are now 32 bit pointers to independently allocated dynamic arrays. Doing it this way, however, earns me an access violation for my troubles. This is apparently not how Delphi expects me to do it. Can anyone explain to me how I am supposed to do this?

Was it helpful?

Solution

A dynamic array is a pointer to a packed block of elements.

So array of array of TSomeRecord is a pointer to an array of pointers, each of which points to a block memory with length(array[firstlevel]) elements, or nil if there are none.

In other words, what you assume is roughly correct, with the addition that arrays with zero elements are nil. Note that you are not supposed to change reference count and length yourself unless you REALLY know what you are doing.

Determining what causes your crash will be hard without example code. Keep in mind that, as for ALL automated Delphi types (except widestring), all dynamic memory must be allocated by the delphi memory manager.

Attempts to that using the memory manager of whatever language you are interfacing to is not possible.

OTHER TIPS

The Language Guide (once available as very useful printed manuals, now finding this info in the online help is very difficult) states:

"A multidimensional array is stored with the rightmost dimension increasing first."

Thereby AFAIK you have not an array of pointers - simply each dimension data one after another, starting from the rightmost one, I guess it's faster because there's no more indirections.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top