Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Межпроцессная переменная


Автор: RinOSpro 26.8.2011, 10:14
Всем привет! В C++ такая замечательная штука, которая позволяет экземплярам одного и того-же exe'шника работать с общей переменной:
Код

#pragma data_seg("Shared") 
volatile LONG g_shared_var = 0;
#pragma data_seg() 

#pragma comment(linker, "/SECTION:Shared,RWS" )


Если этот кусок кода положить в dll, то любой процесс, загрузив эту dll без релоцирования, сможет работать с этой переменной.

Как подобное можно реализовать в Delphi?

Сразу приходит на ум: TCP, UDP, Shared Memory, Pipes, Mailslots, но это как то громоздко для такой, казалось бы простой задачи...

Автор: kami 26.8.2011, 21:30
Цитата(RinOSpro @  26.8.2011,  10:14 Найти цитируемый пост)
позволяет экземплярам одного и того-же exe'шника работать с общей переменной:

Если кто-нибудь объяснит, как это возможно - было бы отлично. Ведь каждый процесс во-первых имеет свою копию dll, а во-вторых - он варится в своем собственном адресном пространстве... Пересечение областей памяти (без специализированных манипуляций) в user-mode, имхо, нереально. Не зря же существует целый раздел IPC.

Автор: northener 26.8.2011, 23:56
Цитата(kami @  26.8.2011,  21:30 Найти цитируемый пост)
Если кто-нибудь объяснит, как это возможно

MMF?

Автор: kami 27.8.2011, 12:54
Цитата(northener @  26.8.2011,  23:56 Найти цитируемый пост)
MMF?

Имхо, не то. Разве что С++ скрывает от программиста его создание и использование. А ну как CreateFileMapping или MapViewOfFile не сработают?

Автор: RinOSpro 29.8.2011, 09:22
Безболезненно как в С++ не получилось... Пришлось писать как раз через:

Цитата(kami @  27.8.2011,  12:54 Найти цитируемый пост)
А ну как CreateFileMapping или MapViewOfFile не сработают?

Ловите может кому пригодится
Код

unit untSharedData;

interface

uses
  Windows, SysUtils;

type
  PSharedData = ^TSharedData;
  TSharedData = record
    Handle: THandle; // Добавьте поля необходимые вам.
  end;

function GetSharedData(AName: string): PSharedData;
function CreateSharedData(AName: string; ASharedData: TSharedData): THandle;  
// Не забудьте выполнить CloseHandle после завершения работы

implementation

function GetSharedData(AName: string): PSharedData;
var
  LMapFile: THandle;
begin
  LMapFile := OpenFileMapping(FILE_MAP_ALL_ACCESS, False, PChar(AName));
  try
    if LMapFile = 0 then
      RaiseLastOSError;

    Result := MapViewOfFile(LMapFile, FILE_MAP_ALL_ACCESS, 0, 0, SizeOf(TSharedData));

    if not Assigned(Result) then
      RaiseLastOSError;
  finally
    CloseHandle(LMapFile);
  end;
end;

function CreateSharedData(AName: string; ASharedData: TSharedData): THandle;
var
  LSharedData: PSharedData;
begin
  Result := CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READWRITE, 0,
    SizeOf(TSharedData), PChar(AName));

  if Result = 0 then
    RaiseLastOSError;

  LSharedData := MapViewOfFile(Result, FILE_MAP_ALL_ACCESS, 0, 0, SizeOf(TSharedData));

  if not Assigned(LSharedData) then
    RaiseLastOSError;

  Move(ASharedData, LSharedData^, SizeOf(TSharedData));
end;

end.


Автор: bems 31.8.2011, 21:38
Цитата(kami @  27.8.2011,  12:54 Найти цитируемый пост)
Имхо, не то. Разве что С++ скрывает от программиста его создание и использование. А ну как CreateFileMapping или MapViewOfFile не сработают? 
Именно то. MMF в native api и DDK не даром называется section. Загрузка исполняемого файла это создание MMF (смотрим флажок SEC_IMAGE). Оно и понятно, если вспомнить что для исполняемых образов в памяти вместо файла подкачки используется сам этот файл на диске.
Так что в общем-то плюсы тут особо не причем, просто там линкеру можно задать SEC_COFF_SHARED а в дельфи, насколько я знаю, нельзя. Ну и если вызов (не CreateFileMapping но смысл почти тот же) провалится, то это отказ при загрузке модуля

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)