2009-10-05 5 views
5

Я пытаюсь вызвать процедуру в DLL Delphi из C#. Процедура ожидает, что вызывающий абонент будет предварительно распределять и вводить array of array of TSomeRecord, из которых он затем будет манипулировать элементами TSomeRecord в качестве средства для возврата результатов. Итак, мне нужно обработать динамические массивы Delphi массивов X.
Теперь I have found here что динамический array of X состоит из указателя на первый элемент динамического массива и что этот первый элемент имеет счетчик ссылок и длину (количество элементов) массива предварённого (оба 32-битные целых числа), и что элементы хранятся инлайн и смежно, так что все это выглядит в памяти:Какова структура памяти динамического массива Delphi динамического массива X?

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

с рррром счетчика ссылок , llll - длина,- элементы и ^, на которые указывает указатель. Это подтверждает; Я тестировал его, и он работает.
Для многомерных динамических массивов я предположил, что можно заменить array of Y для X в array of X, другими словами, что наружный размер просто динамический массив (указателей) динамические массивы, например так:

 
rrrrllll000011112222... 
     ^

где элементы 0000, 1111 и т. д. теперь являются 32-битными указателями на независимо распределенные динамические массивы. Однако делать это таким образом, я получаю нарушение прав доступа к моим неприятностям. По-видимому, это не так, как Delphi ожидает от меня этого. Может ли кто-нибудь объяснить мне, как я должен утра?

ответ

8

Динамический массив - это указатель на упакованный блок элементов.

Таким образом, массив массива TSomeRecord является указателем на массив указателей, каждый из которых указывает на блок-память с элементами длины (array [firstlevel]) или nil, если их нет.

Другими словами, вы предполагаете, что это примерно правильно, с добавлением, что массивы с нулевыми элементами равны нулю. Обратите внимание, что вы не должны самостоятельно менять количество ссылок и длину, если только вы ДЕЙСТВИТЕЛЬНО не знаете, что делаете.

Определение того, что приводит к вашему сбою, будет жестким без примера кода. Имейте в виду, что для ВСЕ автоматизированные типы Delphi (за исключением расширения), вся динамическая память должна выделяться менеджером памяти delphi.

Попытки использовать диспетчер памяти любого языка, с которым вы взаимодействуете, невозможно.

+0

Спасибо за ваш ответ. Я понимаю, что легче диагностировать код (пример), но у меня его нет; только подпись процедуры. DLL - это черный ящик сторонней стороны. –

+0

Тогда единственный совет, который я могу вам дать, - придерживаться принципа, согласно которому тот, кто выделяет, также должен освободить или обернуть DLL в Delphi delphi.exe (comserver) или dll, который удаляет автоматические типы из интерфейса –

0

Руководство Языка (когда доступно очень полезные печатных руководства, теперь найти эту информацию в интерактивной справке очень сложно) заявляет:

«многомерный массив сохраняются с крайним правым размером увеличения первым.»

Таким образом, AFAIK у вас нет массива указателей - просто каждый размер данных один за другим, начиная с самого правого, я думаю, что это быстрее, потому что больше нет указаний.

+0

Фрагмент LG относится к статическим массивам, в то время как вопрос касается динамических массивов. –

+0

Вы правы. Я проверил руководство и хотя макет памяти динамических массивов не детализирован, он говорит, что dynarray может быть «непрямоугольным», и я предполагаю, что единственный способ добиться его состоит в том, чтобы иметь динамический массив anohter как элементы «внешнего», массив. Однако довольно медленный доступ к внутренним. – 2009-10-11 13:59:30