Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.138.200.66] |
|
Сообщ.
#1
,
|
|
|
Изучаю возможность обращения к данным из другого приложения DELPHI.
И в связи с этим вопросы, почему: 1. при считывании блока до 400 байт получается получит данные только первую 1/4 из всего блока? 2. присчитывании блока более 400 байт только 100 не зависимо от размера? 3. почему после UnmapViewOfFile(lpBaseAddress) ни дискриптор ни адрес получить невозможно, хотя во всех примерах перед обращением из другого приложения блоки надо закрыть? |
Сообщ.
#2
,
|
|
|
Цитата Ivan123 @ 1. при считывании блока до 400 байт получается получит данные только первую 1/4 из всего блока? 2. присчитывании блока более 400 байт только 100 не зависимо от размера? Пример кода. где то явно логическая ошибка. должно все работать. Цитата Ivan123 @ 3. почему после UnmapViewOfFile(lpBaseAddress) ни дискриптор ни адрес получить невозможно, хотя во всех примерах перед обращением из другого приложения блоки надо закрыть? UnmapViewOfFile нужно вызвать если тебе блок уже не нужен. можешь спокойно CreateFileMapping\MapViewOfFile во всех программах когда тебе нужно и закрывать когда тебе нужно. память полностью освободится если ты закроешь последний хендл. пс. главное не создать его в монопольном режиме (тогда только один процесс и сможет им воспользоватся) |
Сообщ.
#3
,
|
|
|
Цитата ViktorXP @ UnmapViewOfFile нужно вызвать если тебе блок уже не нужен. Конечно это логично, возможно я сам не до конца в этом разобрался) Что касается первых двух пунктов, вроде интуитивно решил проблему, но понять или найти описание почему именно так поступать нужно не нашёл если я открываю блок виртуальной памяти из того же приложения (форма), где этот блок и создан, то функция должна выглядеть так: MoveMemory(lpBaseAddress, @Vdata , SizeBufIn); а если из другого приложения и из консоли то она уже должна быть выглядеть так: ..................................... SizeBufIn*4); ???? |
Сообщ.
#4
,
|
|
|
сложно понять что ты имеешь ввиду без кода.
Цитата Ivan123 @ а если из другого приложения и из консоли то она уже должна быть выглядеть так: Тебе файл-мапинг нужен для обмена данными между приложениями? "SizeBufIn*4" что это? откуда это берется? ты хочешь передавать данные из нескольких программ по одной объекту "файл мапинга"? не проще ли создать несколько. для каждой операции свой. или сделать очередь за счет семафора |
Сообщ.
#5
,
|
|
|
Цитата ViktorXP @ сложно понять что ты имеешь ввиду без кода Задача состоит: 1. в извлечении одним приложением данных звука (например с микрофона) 2. обработка этих данных вторым приложением 3. вывод результата обработки третьим приложением Поскольку каждое из этих действий занимает достаточно большое время, а хотелось бы получить максимально приближенную к on-line обработке сигнала на выходе, и принята такая схема. Цитата ViktorXP @ "SizeBufIn*4" что это? Вот код третьего приложения 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. |
Сообщ.
#6
,
|
|
|
Цитата Ivan123 @ SizeBufIn*4); ???? Ты имеешь в виду SizeBufOut*4 из коды выше? По моей логике должно быть SizeBufOut*2, т.к. Vdata составляет 400 значений типа integer, которое 2 байтное. Попробуй использовать SizeOf(Vdata) |
Сообщ.
#7
,
|
|
|
Цитата ^D^ima @ Попробуй использовать SizeOf(Vdata) Для того чтобы в третьем приложении мне получить 400 значений мне из второго приложения приходиться отправлять эти 400 значений как SizeBufIn*4, а в тетьем получать как SizeBufOut*4 Добавлено Цитата Ivan123 @ эти 400 значений как SizeBufIn*4 отправить и прочитать 400 или 1600 значений разница большая когда передача и приём on-line |
Сообщ.
#8
,
|
|
|
каждый тип данных имеет свой размер, вы записываете в массив Vdata 400 типов данных integer, поэтому, если один integer имеет размкр 4 байта, то 400*4=1600 байт.
процедура CopyMemory требует третьим аргументом указывать длину в байтах, потому, что она не знает какой тип данных она будет копировать в буфер указанный вторым аргументом, поэтому она копирует SizeBufOut*4, что равно 1600 байт. как написали выше запись SizeBufOut*4 эквивалентна SizeOf(Vdata) при статическом массиве, при динамическом массиве SizeOf будет равен 4 байта. |
Сообщ.
#9
,
|
|
|
Цитата vasya2019 @ если один integer имеет размкр 4 байта с чего вдруг интегер весит 4 байта? |
Сообщ.
#10
,
|
|
|
а сколько?
|
Сообщ.
#11
,
|
|
|
Это я с Word спутал, действительно 4 байта получается. Тогда все сходится 400*4 получается
|
Сообщ.
#12
,
|
|
|
Цитата vasya2019 @ один integer имеет размкр 4 байта, то 400*4=1600 байт Спасибо всем за быстрое реагирование, запутался в размерности данных, теперь всё встало на свои места) |