Qual é o layout de memória de uma matriz dinâmica Delphi da matriz dinâmica de X?

StackOverflow https://stackoverflow.com/questions/1519016

  •  19-09-2019
  •  | 
  •  

Pergunta

Eu estou tentando chamar um procedimento em uma DLL Delphi de C #. O processo espera que o chamador para preallocate e uma entrada array of array of TSomeRecord, da qual serão, em seguida, manipular os elementos TSomeRecord como um meio de resultados de retorno. Então, eu preciso mão-ofício Delphi matrizes dinâmicas de matrizes de X.
Agora, eu encontrei aqui de que um array of X dinâmico consiste de um ponteiro para o primeiro elemento da matriz dinâmico, e que esse primeiro elemento tem uma contagem de referência e o comprimento (número de elementos) da matriz prefixado (ambos inteiros de 32 bits), e que os elementos são armazenados em linha e de forma contígua, de modo que toda a coisa parece como este na memória:

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

rrrr com a contagem de referência, o comprimento llll, 0123 os elementos, e onde os ^ pontos de ponteiro. Isto confirma; Eu testei isso e ele funciona.
Para matrizes dinâmicas multidimensionais presumi que pode substituir array of Y para o X em array of X, em outras palavras, que a dimensão exterior é simplesmente uma matriz dinâmica de (a) ponteiros matrizes dinâmicas, da seguinte forma:

rrrrllll000011112222...
        ^

, onde os elementos 0000, 1111 etc agora são 32 bits ponteiros para matrizes dinâmicas atribuídas independentemente. Fazendo dessa forma, no entanto, ganha-me uma violação de acesso para os meus problemas. Este não é, aparentemente, como Delphi me espera fazê-lo. Alguém pode me explicar como eu am deveria fazer isso?

Foi útil?

Solução

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.

Outras dicas

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top