На главную
ПРАВИЛА FAQ Помощь Участники Календарь Избранное DigiMania RSS
msm.ru
! ПРАВИЛА РАЗДЕЛА · FAQ раздела Delphi · Книги по Delphi
Пожалуйста, выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.
Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
2. Как "свернуть" программу в трей.
3. Как "скрыться" от Ctrl + Alt + Del (заблокировать их и т.п.)
4. Как прочитать список файлов, поддиректорий в директории?
5. Как запустить программу/файл?
... (продолжение следует) ...

Вопросы, подробно описанные во встроенной справочной системе Delphi, не несут полезной тематической нагрузки, поэтому будут удаляться.
Запрещается создавать темы с просьбой выполнить какую-то работу за автора темы. Форум является средством общения и общего поиска решения. Вашу работу за Вас никто выполнять не будет.


Внимание
Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка - 60 дней. Последующие попытки бан.
Мат в разделе - бан на три месяца...
Модераторы: jack128, D[u]fa, Shaggy, Rouse_
  
> MapViewOfFile и MoveMemory порядок взаимодействия
Изучаю возможность обращения к данным из другого приложения DELPHI.
И в связи с этим вопросы, почему:
1. при считывании блока до 400 байт получается получит данные только первую 1/4 из всего блока?
2. присчитывании блока более 400 байт только 100 не зависимо от размера?
3. почему после UnmapViewOfFile(lpBaseAddress) ни дискриптор ни адрес получить невозможно, хотя во всех примерах перед обращением из другого приложения блоки надо закрыть?
Сообщение отредактировано: Ivan123 -
Цитата Ivan123 @
1. при считывании блока до 400 байт получается получит данные только первую 1/4 из всего блока?
2. присчитывании блока более 400 байт только 100 не зависимо от размера?

Пример кода. где то явно логическая ошибка. должно все работать.

Цитата Ivan123 @
3. почему после UnmapViewOfFile(lpBaseAddress) ни дискриптор ни адрес получить невозможно, хотя во всех примерах перед обращением из другого приложения блоки надо закрыть?

UnmapViewOfFile нужно вызвать если тебе блок уже не нужен. можешь спокойно CreateFileMapping\MapViewOfFile во всех программах когда тебе нужно и закрывать когда тебе нужно. память полностью освободится если ты закроешь последний хендл.
пс. главное не создать его в монопольном режиме (тогда только один процесс и сможет им воспользоватся)
select name, telephone from Girls where age between 20 and 25 and (.)(.) >= 2 order by IQ desc limit 1
Цитата ViktorXP @
UnmapViewOfFile нужно вызвать если тебе блок уже не нужен.

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

MoveMemory(lpBaseAddress, @Vdata , SizeBufIn);

а если из другого приложения и из консоли то она уже должна быть выглядеть так:

..................................... SizeBufIn*4); ????
Сообщение отредактировано: Ivan123 -
сложно понять что ты имеешь ввиду без кода.
Цитата Ivan123 @
а если из другого приложения и из консоли то она уже должна быть выглядеть так:

Тебе файл-мапинг нужен для обмена данными между приложениями?
"SizeBufIn*4" что это? откуда это берется? ты хочешь передавать данные из нескольких программ по одной объекту "файл мапинга"? не проще ли создать несколько. для каждой операции свой. или сделать очередь за счет семафора
select name, telephone from Girls where age between 20 and 25 and (.)(.) >= 2 order by IQ desc limit 1
Цитата ViktorXP @
сложно понять что ты имеешь ввиду без кода


Задача состоит:
1. в извлечении одним приложением данных звука (например с микрофона)
2. обработка этих данных вторым приложением
3. вывод результата обработки третьим приложением
Поскольку каждое из этих действий занимает достаточно большое время, а хотелось бы получить максимально приближенную к on-line обработке сигнала на выходе, и принята такая схема.

Цитата ViktorXP @
"SizeBufIn*4" что это?


Вот код третьего приложения


ExpandedWrap disabled
    unit U6_1;
     
    interface
     
    uses
      Windows, Math, Messages, Classes, Forms, MMSystem;
    procedure Execute;
    const
        discret = 8000;
        SizeBufOut = 400;
        MMFName: pAnsiChar = 'MP';
        a=0;
     
    type
      TForm1 = class(TForm)
        procedure FormCreate(Sender: TObject);
      public
        procedure WCard;
      end;
     
    var
        hMapFile:THandle;
        lpBaseAddress:PChar;
        Vdata: array [0..SizeBufOut-1] of integer;
     
        Form1: TForm1;
        WaveFormatEx: TWaveFormatEx;
        WaveOut:HWAVEOUT;
        hEvent: THandle;
        woh: WAVEHDR;
        BufHead: TWaveHdr;
        n: word;
     
    implementation
     
    {$R *.dfm}
     
    procedure TForm1.FormCreate(Sender: TObject);
    begin
        WCard;
        Execute;
    end;
     
    procedure TForm1.WCard;
    var
      BufLen: word;
      n: word;
     
      begin
        with WaveFormatEx do
        begin
          wFormatTag := WAVE_FORMAT_PCM;
          nChannels := 1;
          nSamplesPerSec := discret;
          wBitsPerSample := 16;
          nBlockAlign := nChannels * (wBitsPerSample div 8);
        end;
     
        hMapFile := OpenFileMapping(FILE_MAP_ALL_ACCESS,False,MMFName);
        lpBaseAddress := MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 1);
     
        hEvent := CreateEvent(nil, false, false, nil);
        WaveOutOpen(Addr(WaveOut), 0, addr(WaveFormatEx), hEvent, 0,CALLBACK_EVENT);
        waveOutPrepareHeader(WaveOut, addr(woh),SizeOf(woh));
        BufLen := WaveFormatEx.nBlockAlign * SizeBufOut;
        with BufHead do
          begin
            woh.lpData := addr(Vdata);
            woh.dwBufferLength := BufLen;
          end;
      end;
     
    procedure Execute;
      begin
        while a<1 do
          begin;
            CopyMemory(addr(Vdata), lpBaseAddress, SizeBufOut*4);/здесь получаем данные из второго приложения (почему всё таки *4?)
            waveOutWrite(WaveOut, addr(woh), SizeOf(woh));
            waveOutReset(WaveOut);
          end;
      end;
     
     
    end.
Цитата Ivan123 @
SizeBufIn*4); ????


Ты имеешь в виду SizeBufOut*4 из коды выше?
По моей логике должно быть SizeBufOut*2, т.к. Vdata составляет 400 значений типа integer, которое 2 байтное. Попробуй использовать SizeOf(Vdata)
"Воля - это то, что заставляет тебя побеждать, когда твой рассудок говорит тебе, что ты повержен" Карлос Кастанеда
Цитата ^D^ima @
Попробуй использовать SizeOf(Vdata)

Для того чтобы в третьем приложении мне получить 400 значений мне из второго приложения приходиться отправлять эти 400 значений как SizeBufIn*4, а в тетьем получать как SizeBufOut*4

Добавлено
Цитата Ivan123 @
эти 400 значений как SizeBufIn*4

отправить и прочитать 400 или 1600 значений разница большая когда передача и приём on-line
Сообщение отредактировано: Ivan123 -
каждый тип данных имеет свой размер, вы записываете в массив Vdata 400 типов данных integer, поэтому, если один integer имеет размкр 4 байта, то 400*4=1600 байт.

процедура CopyMemory требует третьим аргументом указывать длину в байтах, потому, что она не знает какой тип данных она будет копировать в буфер указанный вторым аргументом, поэтому она копирует SizeBufOut*4, что равно 1600 байт.

как написали выше запись SizeBufOut*4 эквивалентна SizeOf(Vdata) при статическом массиве, при динамическом массиве SizeOf будет равен 4 байта.
Цитата vasya2019 @
если один integer имеет размкр 4 байта

с чего вдруг интегер весит 4 байта?
"Воля - это то, что заставляет тебя побеждать, когда твой рассудок говорит тебе, что ты повержен" Карлос Кастанеда
а сколько?
Это я с Word спутал, действительно 4 байта получается. Тогда все сходится 400*4 получается
"Воля - это то, что заставляет тебя побеждать, когда твой рассудок говорит тебе, что ты повержен" Карлос Кастанеда
Цитата vasya2019 @
один integer имеет размкр 4 байта, то 400*4=1600 байт

Спасибо всем за быстрое реагирование, запутался в размерности данных, теперь всё встало на свои места)
Сообщение отредактировано: Ivan123 -
1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
0 пользователей:


Рейтинг@Mail.ru
[ Script Execution time: 0,1354 ]   [ 20 queries used ]   [ Generated: 19.02.19, 11:38 GMT ]