Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Вопросы по Embarcadero RAD Studio XE2 (Pulsar)

Модерирует : ShIvADeSt

 Версия для печати • ПодписатьсяДобавить в закладки
Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57

Открыть новую тему     Написать ответ в эту тему

data man



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Обсуждаем новые возможности и баги
Просьба писать только про Embarcadero RAD Studio XE2 (Pulsar) - по остальным версиям есть соответствующие темы.

Вопросы вареза здесь не обсуждаются !!!
См. также:


Из слишком часто повторяемых вопросов:
  1. Почему EXE такие большие - перевод статьи от Andy тут, оригинал на страницу назад.
  2. Что случилось c авто-увеличением Build Number - Объяснение на англ.. Можно отключить встроенную функцию и добавить плагин, в котором есть "старый" авто-инкремент. Например DDevExtensions от Andy. У него так же есть хороший плагин IDE FixPack

Всего записей: 1696 | Зарегистр. 13-10-2005 | Отправлено: 23:54 27-07-2011 | Исправлено: Arioch1, 16:08 25-04-2013
Arioch1



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
не надо! он там был! с вопросами из справки...
 
лучше на http://hashcode.ru/

Всего записей: 904 | Зарегистр. 03-03-2010 | Отправлено: 12:34 04-04-2012
stupid_user

Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Приветствую всех!
Есть одна проблема. Подключаю стороннюю библиотеку (написана была на СИ-подобном) и в функцию передаю структуру как параметр
 
если делаю вот так, то все работает.

Код:
  TLevel = record
    iValue1: Integer;
    iValue2: Integer;
    iValue3: Integer;
  end;
 
  TMainLevels = record
    iSize: Integer;
    iReserved: Integer;
    aLevels: array[0..2] of TLevel;

Функция отрабатывает нормально.
 
Но суть в том что aLevels должен быть динамическим массивом
 

Код:
  TLevel = record
    iValue1: Integer;
    iValue2: Integer;
    iValue3: Integer;
  end;
 
  TMainLevels = record
    iSize: Integer;
    iReserved: Integer;
    aLevels: array of TLevel;

 
Но так ничего не работает.  
 
   
 
Как мне правильно объявить такой динамический массив? или что-то еще надо сделать? чтобы в памяти он располагался последовательно без использования указателя.

Всего записей: 292 | Зарегистр. 12-11-2006 | Отправлено: 14:12 04-04-2012
Arioch1



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Никак. Динамический массив - всегда указатель, потому что длина неизвестна.
 
Какой размер в байтах у твоей TMainLevels ? компилятор его должен знать заранее.
 
ЗАчем тебе это вообще нужно, чтобы была переменная длина ?
 
Добавлено:
  TMainLevels = TList<TLevel>

Всего записей: 904 | Зарегистр. 03-03-2010 | Отправлено: 14:19 04-04-2012 | Исправлено: Arioch1, 14:20 04-04-2012
stupid_user

Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
Какой размер в байтах у твоей TMainLevels ?
iSize = SizeOf(TLevel) + ( SizeOf(TLevel)* количество элементов TLevel)

Цитата:
ЗАчем тебе это вообще нужно, чтобы была переменная длина ?
количество элементов TLevel заранее не известно. опытным путем установил что в текущий момент оно было 44 байта (8 байт TMainLevel + остальное из TLevel)
 

Всего записей: 292 | Зарегистр. 12-11-2006 | Отправлено: 14:33 04-04-2012 | Исправлено: stupid_user, 14:34 04-04-2012
Arioch1



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
компилятор его должен знать заранее.

Количество должно быть определено до начала компиляции, либо же нельзя вставить массив.
 
 

Цитата:
Описывайте конечную цель, а не отдельные шаги
 
Если вы пытаетесь разобраться как что-либо сделать (а не сообщать об ошибке), начинайте с описания цели. И только потом описывайте конкретный шаг на пути к ней, который вы не смогли выполнить.
 
http://maddog.sitengine.ru/smart-question-ru.html#goal

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

Цитата:
 {$T+}
 
      TLevel = packed record   iValue1,  iValue2, iValue3: Integer; end;  
      PLevel = ^TLEvel;
 
  TMainLevels = packed record  
     iSize: Integer;  
     iReserved: Integer;  
     aLevels: array[0..0] of TLevel;
 
     function SelfPtr: Pointer;
     function NextItem: Pointer;
     function SizeOf: Integer;
 
     procedure CheckIdx(const i: integer); inline;
     procedure setter(const idx: integer; const Value: PLevel); inline;
     procedure getter(const idx: integer): PLevel; inline;
     property Levels[I:integer]: PLevel read getter write setter;
  end;
 
 
  function TMainLevels.SizeOf: Integer;
  begin
      Result := SizeOf(TMainLevels) + (-1 + iSize)*SizeOf(TLevel);
  end;
 
  function TMainLevels.SelfPtr: Pointer;
  begin Result := @iSize; // для разных типов - разный элемент первый
     // возможно хватило бы @Self, не помню, проверять лень
  end;
 
  function TMainLevels.NextItem: Pointer;
  begin Result := SelfPtr; Inc(Result, SizeOf); end;
 
  procedure TMainLevels.CheckIdx(const i: integer);
  begin
    {$IfOpt R+}
      if (i<0) or (i>= iSize) then
         raise ERangeError.CreateFmt ('Levels are from #0 to #%d, access attempted to #%d', [iSize - 1, i]);
    {$EndIf}
  end;
 
  {$UnDef WasRangeChecking}  
  {$IfOpt R+} {$Define WasRangeChecking} {$R-} {$EndIF}
 
  procedure TMainLevels.setter(const idx: integer; const Value: PLevel);
  begin
      CheckIdx(idx);
      aLevels[idx] := Value^;
  end;  
 
  procedure TMainLevels.getter(const idx: integer): PLevel;
  begin
      CheckIdx(idx);
      Result := @aLevels[idx];
  end;  
  {$ifDef WasRangeChecking} {$R+} {$UnDef WasRangeChecking}  {$EndIF}
 
.....
 
var ScanningPtr: Pointer;
 
.....
    while ... do begin
       
        if тип элемента TMainLevels then with TMainLevels(ScanningPtr)^ do begin
                xyz := Levels[2]^.iValue2;
...
                ScanningPtr := NextItem;
                continue;              
        end;
 
        if тип элемента какой-другой-тип then ...
 
        if тип элемента какой-другой-тип then ...
 
    end;
 

 
 
Другой вариант разбора структуры (парсинга) файлов был описан http://synopse.info/forum/viewtopic.php?pid=3950, там вместо записей использовали объекты (но не классы!). Впрочем, объекты скорее всего удалят в следующих версиях Дельфи рано или поздно.

Всего записей: 904 | Зарегистр. 03-03-2010 | Отправлено: 16:13 04-04-2012 | Исправлено: Arioch1, 16:18 04-04-2012
stupid_user

Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Arioch1
спасибо! по твоему коду выбрал необходимые куски

Всего записей: 292 | Зарегистр. 12-11-2006 | Отправлено: 16:27 04-04-2012
Arioch1



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
да здесь по-моему все куски нужны.
 
но дело твоё

Всего записей: 904 | Зарегистр. 03-03-2010 | Отправлено: 16:30 04-04-2012
Frodo_Torbins

Silver Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
stupid_user
Не передавайте в функцию рекорды, передавайте в нее выделенный вручную кусок памяти, в который записывайте все нужные данные. Можно сделать вокруг этого красивую обертку в виде класса.

Всего записей: 2318 | Зарегистр. 24-05-2007 | Отправлено: 16:51 04-04-2012
Man_Without_Face



Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
del

Всего записей: 381 | Зарегистр. 25-01-2010 | Отправлено: 13:11 05-04-2012 | Исправлено: Man_Without_Face, 13:19 05-04-2012
delover

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Man_Without_Face

 
stupid_user
У сишных программ на этот счёт есть шаблон, который сможет понять программист который когда либо в глаза видел TList ранних версий дельфи, не XE2.  Массив объявляется максимальной длинны которую позволит компилятор - как правило 4 гигобайта массив. Далее выделяется память равная количество элементов помноженное на длину элемента - выделяется под массив. Через GetMem(N*Sizeof) - это делается вручную. Динамические массивы Delphi позваляют не делать этого в ручную и они не подходят по двум причинам.
 

Код:
packed record
  count: byte;
  a: array of TMyType;
end;

- Размер этой структуры 5 байт (count + ссылка на динамический массив)
 

Код:
packed record
  count: byte;
  a: array[byte] of TMyType;
end;

- Полный размер этой структуры равет 1 байт + Sizeof(TMyType)*256, но в языке Си принято что размер этой структуры равен 1 байт + Sizeof(TMyType)*count.
 
Соответственно - это совершенно разные данные. Если библиотека была писана на сях то второй вариант вычисления. Вместо count чаже бывает реальный Sizeof, тогда count вычисляется по обратной формуле.
 
ЗЫ
array of Type - это динамический массив и переменная этого типа имеет всегда 4 байта на указатель для 32-х битных программ.

Всего записей: 1395 | Зарегистр. 25-06-2007 | Отправлено: 18:45 09-04-2012
Arioch1



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
 как правило 4 гигобайта массив

а не 2 ? в Win32 на приложение целиком отводится только 2.  
от силы, в спец-версиях Windows, три.

Всего записей: 904 | Зарегистр. 03-03-2010 | Отправлено: 13:10 10-04-2012
Frodo_Torbins

Silver Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Arioch1
Декларироваться может и четыре, но реально даже один выделить не получится. Правда никто и не пытается.

Всего записей: 2318 | Зарегистр. 24-05-2007 | Отправлено: 13:50 10-04-2012
Arioch1



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
xe2 win32 mode
 
const mx = high(cardinal) - 1000;
type tx = array [0..mx] of byte;
 
[DCC Error] Main.pas(35): E2100 Data type too large: exceeds 2 GB
[DCC Fatal Error] Test.dpr(5): F2063 Could not compile used unit 'Main.pas'

Всего записей: 904 | Зарегистр. 03-03-2010 | Отправлено: 14:18 10-04-2012
Frodo_Torbins

Silver Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Arioch1
Речь шла не о делфи.

Всего записей: 2318 | Зарегистр. 24-05-2007 | Отправлено: 14:57 10-04-2012
delover

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Arioch1
Спасибо за поправку, - 4. Я про Delphi2 ну или 2010. Реально не предполагалось занимать места ограниченные системой. Речь действительно о типах Си, но в приложении к Делфи.

Всего записей: 1395 | Зарегистр. 25-06-2007 | Отправлено: 17:41 10-04-2012
Arioch1



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
а тогда вообще не имеет значение ограничение компилятора.
 
Выключаешь Range Checking, делаешь массив [0..0] и понеслась.
 
Я вот не помню, включает ли Pointer Math такую Сишную фишку, что указатель и массив - это один и тот же тип.
Скорее всего нет, потому чт опо уммолчанию выключен Typed Pointer.
 
Добавлено:
Впрочем, при сканировании массива, проще сделать указатель на 1-й элемент, а потом его в цикле увеличивать
IMHO

Всего записей: 904 | Зарегистр. 03-03-2010 | Отправлено: 17:48 10-04-2012
delover

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Arioch1
Вы начали отлично а аконцовка лучше бы Вы этого никому больше не говорили. Мароз или параноя там, но у техники - как у инструмента есть свои места.

Всего записей: 1395 | Зарегистр. 25-06-2007 | Отправлено: 21:59 10-04-2012
Arioch1



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Ы? что конкретно сказать то хотел ?

Всего записей: 904 | Зарегистр. 03-03-2010 | Отправлено: 22:06 10-04-2012
delover

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
сорри тогда не былор времени.

Цитата:
а тогда вообще

Тогда вообще имеют ограничения только способности компилятора. А системные ограничения это бунус к Виза кард банк. Если вспомните дорогу - приходите.

Всего записей: 1395 | Зарегистр. 25-06-2007 | Отправлено: 22:09 10-04-2012
A_V

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Arioch1

Цитата:
от силы, в спец-версиях Windows, три

Что за спец-версии? Это всмысле ключ /3GB?

Цитата:
Я вот не помню, включает ли Pointer Math такую Сишную фишку, что указатель и массив - это один и тот же тип

{$POINTERMATH ON}? ну не один и тот-же тип конечно, но обращаться через [] к указателю можно.

Всего записей: 770 | Зарегистр. 07-04-2002 | Отправлено: 22:20 10-04-2012 | Исправлено: A_V, 22:21 10-04-2012
Открыть новую тему     Написать ответ в эту тему

Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57

Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Вопросы по Embarcadero RAD Studio XE2 (Pulsar)


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2024

BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

Рейтинг.ru