Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Подскажите как правильно сделать отложенную обрабо 
:(
    Опции темы
CodeMonkey
Дата 15.7.2008, 15:28 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1839
Регистрация: 24.6.2008
Где: Россия, Тверь

Репутация: 16
Всего: 89



Цитата(vogel @  15.7.2008,  14:55 Найти цитируемый пост)
Реализация с WM_COPYDATA оказалась наиболее простой и понятной, но и у неё есть свои недостсаки - как-то передача блоков только фиксированного рамера. В итоге, зная, что данные у меня длиногй максимум word - пришлось делать массив [0..$FFFF]. Это работает, но приносит дополнительные расходы, ибо размер передаваемых данных всегда разный и в-основном значительно меньше FFFF.

Непонятно, откуда вы это взяли?
В вашем же примере:
Цитата(vogel @  11.7.2008,  18:14 Найти цитируемый пост)
Код
    copyDataStruct.cbData := sizeOf(msg); // Явно указываете размер данных, т.е. он может быть произвольным
    copyDataStruct.lpData := @msg; // Любые данные

Т.е. у вас уже написан код по передаче данных любого размера. Правда конкретно сейчас вы передаёте только одну запись фиксированного размера (TIPCMessage). Или вы говорите, что не знаете, как подготовить (упаковать в запись или что-то такое) данные произвольной длины для отправки?

Цитата(vogel @  15.7.2008,  14:55 Найти цитируемый пост)
Однако, я не уверен, что через MMF можно будет просто кидать динамические массивы или строки.

Точно так же, как любые другие данные. При передаче вы все данные всё равно рассматриваете как массив (набор) байт, без разницы: строка это, запись или массив.



--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
vogel
Дата 22.7.2008, 16:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 12.12.2007

Репутация: нет
Всего: нет



Конкретно, если мне надо передать запись где есть строки, объявленные как string, делаем это, напрмер, так :

Код

TSomeRecord = record
  ...
  ID : integer;
  Size : word;
  Data : string;
   ...
end;


и дальше в коде :

Код

var
  Message : TSomeRecord;
begin
...
Message.Size := len;
setlength(Message.Data, Message.Size);
move(Buffer[0], Message.Data[1], Message.Size);
...
end;


получаем, что sizeOf(TSomeRecord) совсем не равен реальному размеру записи. И припопытке вычитать такую строку получаем AV.

Однако, если я использую вместо string - array[0..$FFFF] of char, то всё работает прекрасно, хоть и значительно перерасходуется память.

Это сообщение отредактировал(а) vogel - 22.7.2008, 16:03
PM MAIL   Вверх
Snowy
Дата 22.7.2008, 16:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 30
Всего: 484



Разумеется.
Ведь string - это указатель.
Передавать такую структуру через WM_COPYDATA бесполезно.
Нужно передавать фиксированный блок.
Либо использовать записи строгого размера, либо записать все данные в единый буфер/стрим.
Записать данные можно вручную, либо через сериализацию.
Ситуация подобна передаче данных через сокеты. Нужно передавать сплошной блок/поток данных, а не указатели на них.
PM MAIL   Вверх
CodeMonkey
Дата 22.7.2008, 17:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1839
Регистрация: 24.6.2008
Где: Россия, Тверь

Репутация: 16
Всего: 89



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

Грубо говоря, вы должны разделить данные на данные фиксированного размера и динамические. Закиньте все фиксированные данные в структуру:

Код
TSomeRecord = record
  ...
  ID : integer;
  Size : word;
   ...
end;


Далее, вы должны подготовить блок к передаче, например, так:

Код
var
  P: TSomeRecord;
  MS: TMemoryStream;
  X: Integer;
...
// Готовите фиксированную часть
P.ID := 3;
...

// Далее, собираем всё в кучу
MS := TMemoryStream.Create;
try
  // Динамические данные пишутся как: [длина данных] [сами данные]
  X := Length(S);
  MS.WriteBuffer(X, SizeOf(X));
  if X > 0 then
    MS.WriteBuffer(Pointer(S)^, X);

  // Теперь здесь MS.Memory - указатель на данные для пересылки. Все данные оказались упакованными в один блок.

finally
  FreeAndNil(MS);
end;  


Ну и читать аналогично, только все действия в обратном порядке.


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • 99% ответов по WinAPI можно найти в MSDN Library, оставшиеся 1% здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.0468 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.