Какова структура памяти динамического массива Delphi для динамического массива X?
-
19-09-2019 - |
Вопрос
Я пытаюсь вызвать процедуру в DLL Delphi из C#.Процедура ожидает, что вызывающая сторона предварительно выделит и введет array of array of TSomeRecord
, из которых он затем будет манипулировать TSomeRecord
элементы как средство возврата результатов.Итак, мне нужно вручную создать динамические массивы Delphi из массивов X.
Сейчас, Я нашел здесь что динамика array of X
состоит из указателя на первый элемент динамического массива, и что этот первый элемент имеет счетчик ссылок и длину (количество элементов) добавленного в начале массива (оба 32-битных целых числа), и что элементы хранятся в строке и последовательно, так что в памяти все это выглядит так:
rrrrllll000...000111...12... ^
где rrrr — счетчик ссылок, llll — длина, 0123 — элементы и ^, куда указывает указатель.Это подтверждается;Я проверил это, и это работает.
Я предположил, что для многомерных динамических массивов можно заменить array of Y
для X
в array of X
, Другими словами, внешнее измерение — это просто динамический массив динамических массивов (указателей на них), например:
rrrrllll000011112222... ^
где элементы 0000, 1111 и т. д. теперь являются 32-битными указателями на независимо выделенные динамические массивы.Однако поступая таким образом, я получаю нарушение прав доступа из-за своих проблем.Очевидно, Delphi ожидает, что я это сделаю не так.Может ли кто-нибудь объяснить мне, как я являюсь должен это сделать?
Решение
Динамический массив — это указатель на упакованный блок элементов.
Таким образом, массив массива TSomeRecord является указателем на массив указателей, каждый из которых указывает на блочную память с элементами length(array[firstlevel]) или ноль, если их нет.
Другими словами, то, что вы предполагаете, примерно верно, с учетом того, что массивы с нулевыми элементами равны нулю.Обратите внимание: вам не следует самостоятельно изменять количество и длину ссылок, если вы ДЕЙСТВИТЕЛЬНО не знаете, что делаете.
Без примера кода определить причину сбоя будет сложно.Имейте в виду, что, что касается ВСЕ автоматические типы Delphi (кроме Widestring), вся динамическая память должна быть выделена менеджером памяти Delphi.
Попытки сделать это с помощью диспетчера памяти любого языка, с которым вы взаимодействуете, невозможны.
Другие советы
Языковое руководство (когда-то доступное в виде очень полезных печатных руководств, теперь найти эту информацию в онлайн-справке очень сложно) гласит:
«Многомерный массив хранится так, что сначала увеличивается самое правое измерение».
Таким образом, AFAIK, у вас нет массива указателей - просто данные каждого измерения один за другим, начиная с самого правого, я думаю, это быстрее, потому что больше нет косвенных направлений.