Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2002.12.02;
Скачать: CL | DM;

Вниз

Общий ресурс из dll для 2х процессов. Проблема !!!   Найти похожие ветки 

 
UnDISCOvery ©   (2002-11-19 16:31) [0]

есть вот такая структура:
type
PGlobalDLLData = ^TGlobalDLLData;
TGlobalDLLData = record
S: String[50];
I: Integer;
M: TMemoryStream;
end;
Она общая для двух процессов, грузится из длл-ки. За основу взят пример из Пачеко.
----------------------------------
в длл:
GlobalData^.M := TMemoryStream.Create;
Path:=GetCurrentDir+"\BMP\111.bmp";
GlobalData^.M.LoadFromFile(Path);
-----------------------------------
в App1.exe

procedure TMainForm.LoadNextBmp;
begin
lbCount.Caption:= IntToStr(ImgCount);
try
GetDLLData(GlobalData);
GlobalData^.I:= ImgCount;
GlobalData^.M.Position:=0;
BmpArr[ImgCount].SaveToStream(GlobalData^.M);
except
ShowMessage(SysErrorMessage(GetLastError));
end;
inc(ImgCount);
if ImgCount > 3 then ImgCount:=0;
end;
---------------------------------------
в App2.exe

procedure TMainForm.btnGetGlobalDataClick(Sender: TObject);
var
Size: integer;
begin
try
GetDllData(GlobalData);
lblGlobDataStr.Caption := GlobalData^.S;
lblGlobDataInt.Caption := IntToStr(GlobalData^.I);
GlobalData^.M.Position:=0;
Image1.Picture.Bitmap.LoadFromStream(GlobalData^.M);
except
ShowMessage(SysErrorMessage(GetLastError));
end;
end;
-----------------------------------

Как видно, первое приложение циклически меняет данные общего ресурса. Второе приложение должно воспринять эти изменения.
Проблема: второе приложение не видит новые картинки из BmpArr.
В чем проблема ? Как правильно их передать ?


 
Skier ©   (2002-11-19 16:37) [1]

>UnDISCOvery
GlobalData^.M := TMemoryStream.Create;
Path:=GetCurrentDir+"\BMP\111.bmp";
GlobalData^.M.LoadFromFile(Path);

А путь случаем не один и тот же ?


 
MBo ©   (2002-11-19 16:45) [2]

да не TMemoryStream надо в общей памяти держать, а сырые данные, а вот MemoryStream.Memory надо заставить на этот адрес указывать
(SetPointer), а надежнее, IMHO, копировать кусок памяти


 
UnDISCOvery ©   (2002-11-19 16:46) [3]

А при чем здесь это ?
Не понял вопроса ... :-/
в принципе - можно и не грузить по умолчанию картинку, все равно ничего не измениться ...


 
UnDISCOvery ©   (2002-11-19 17:07) [4]

> MBo
1. что значит "сырые данные" ?
2. каков механизм "копирования куска памяти" ?


 
MBo ©   (2002-11-19 17:14) [5]

при создании объекта приведенным тобой образом в общей памяти лежит указатель на объект, а сами данные - в адресном пространстве кладущего процесса.
Создав TMemoryStream и записав в него битмап, получи указатель на данные через MemoryStream.Memory, и скопируй Move MS.Size байт в общую память. В принимающей программе сделай MS.Size=нужному размеру (значение которого тоже надо держать в общей памяти) и Move из shared памяти в адрес MemoryStream.Memory


 
reonid ©   (2002-11-19 19:19) [6]

Лучше направить поток прямиком в расшаренную память:

(если копировать - уж слишком много копий возникает -
одна в самом битмапе, другая в мемористриме, третья -
в файлмаппинге - и так в обоих приложениях)

PGlobalDLLData = ^TGlobalDLLData;
TGlobalDLLData = record
S: String[50];
I: Integer;
//...
StreamDataBeginning: Integer; // сюда и далее будет писать поток
end;

//-------------------------------------------------
type
TFixedMemoryStream = class(TCustomMemoryStream)
public
constructor Create(Ptr: Pointer; Size: Longint);
function Write(const Buffer; Count: Longint): Longint; override;
end;

constructor TFixedMemoryStream.Create(Ptr: Pointer; Size: Integer);
begin
SetPointer(Ptr, Size);
end;

function TFixedMemoryStream.Write(const Buffer; Count: Longint): Longint;
var
Pos: Longint;
begin
if (Position >= 0) and (Count >= 0) then
begin
Pos := Position + Count;
if Pos > 0 then
begin
if Pos > Size then raise EStreamError.CreateFmt("%s: overflow", [ClassName]);

System.Move(Buffer, Pointer(Longint(Memory) + Position)^, Count);
Position := Pos;
Result := Count;
Exit;
end;
end;
Result := 0;
end;
//-----------------------------------------------

// при чтении или записи битмапа в поток нужно
// этот поток создавать динамически:

GetDllData(GlobalData);
Stream := TFixedMemoryStream.Create(@GlobalData^.SteamDataBeginning,
SizeOfFileMapping // размер FileMapping"a - я не знаю, чему он у тебя равен
// Но он должен быть достаточен для
// вмещения твоих битмапов.

- SizeOf(TGlobalDLLData) );

try
Stream.Position := 0;

BmpArr[ImgCount].SaveToStream(Stream);

// пишешь/читаешь из потока - поток пишет напрямую в
// расшаренный регион
...
finally
Stream.Free;
end;

Тут возникает уже вопрос синхронизации - как одно приложение узнает, что другое записало данные и пора их читать.
- нужно, вероятно, использовать мютекс + WaitForSingleObject.

PS Я не понял - тебе нужно в течение работы
менять содержимое битмапов,
так чтобы другое приложение отслеживало эти изменения,
или же нужно выбирать из уже существующих битмапов, не меняя
их изображения?



Страницы: 1 вся ветка

Текущий архив: 2002.12.02;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.018 c
1-4363
Борис
2002-11-21 16:52
2002.12.02
ShellExecute Как заставить IE зарузить новую страницу


3-4185
nikolo
2002-11-13 11:31
2002.12.02
Хранимые процедуры MS SQL (несколько RecordSet)


1-4438
V-A-V
2002-11-20 08:33
2002.12.02
поиск в TreeView


14-4629
iNew
2002-11-11 17:44
2002.12.02
Слушайте, а как мне свою анкету отредактировать


3-4265
Filat
2002-11-08 15:54
2002.12.02
Компонент VGLib и работа с закладками