Форум: "Основная";
Текущий архив: 2002.12.02;
Скачать: [xml.tar.bz2];
ВнизОбщий ресурс из 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;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.006 c