Я пытаюсь выяснить, как разделить объект между несколькими приложениями в Delphi. Я знаю, что способ сделать это через вызовы IPC/Windows для общей памяти (т. Е. CreateFileMapping и т. Д.), Однако во всем примере кода, который я нашел, они используют простой тип, например строку, тогда как мне нужно разделить объект.обмен объектами между несколькими приложениями в Delphi
Мне интересно, возможно ли это, так как я продолжаю заканчивать приложение, которое просто разделяет ссылку указателя на объект, но не сама память объекта. Когда я пытаюсь получить и затем получить доступ к объекту из другого приложения, я получаю нарушение доступа. Я думаю, это потому, что указатель относится к защищенной памяти из другого приложения.
Вот код, который я пробовал до сих пор (как вы можете видеть, я пытаюсь разделить объект TADOConnection между несколькими приложениями, так что между приложениями используется только одно соединение с базой данных). Если там есть лучший/более простой способ сделать это (совместное использование ADO-соединения), мне интересно узнать, как это сделать.
TSharedData = record
Connection: TAdoConnection;
end;
PSharedData = ^TSharedData;
var
SharedData: PSharedData;
hFileMapping: THandle;
Form1: TForm1;
implementation
{$R *.dfm}
function CreateNamedFileMapping(const Name: String): THandle;
begin
Result := CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READWRITE, 0,
SizeOf(TSharedData)*8, PChar(Name));
if Result > 0 then
SharedData := MapViewOfFile(Result, FILE_MAP_ALL_ACCESS, 0, 0, 0);
end;
function GetSharedData: PSharedData;
begin
result := nil;
hFileMapping := OpenFileMapping(FILE_MAP_ALL_ACCESS, False, 'MySharedMemory');
if (hFileMapping > 0) then
Result := MapViewOfFile(hFileMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0);
end;
procedure TForm1.createClick(Sender: TObject);
begin
hFileMapping := CreateNamedFileMapping('MySharedMemory');
if (hFileMapping > 0) and Assigned(SharedData) then
begin
SharedData^.Connection := TAdoConnection.Create(nil);
// can't use Assign as it is not supported by _Connection
SharedData^.Connection.ConnectionObject := AdoConnection1.ConnectionObject;
end;
end;
procedure TForm1.retrieveClick(Sender: TObject);
begin
SharedData := GetSharedData;
if assigned(SharedData) then
// should be set to true if everything was ok
ShowMessage(BoolToStr(SharedData.Connection.Connected, true));
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
AdoConnection1.Connected := False;
if assigned(SharedData) then
UnmapViewOfFile(SharedData);
if hFileMapping > 0 then
CloseHandle(hFileMapping);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
AdoConnection1.Connected := true;
end;
end.
ADOConnection1 - это объект на моей форме. Я знаю, что мне нужно скопировать всю память объекта, используя что-то вроде «Assign», однако этого не существует в ADO ConnectionObject. Чтобы убедиться, что проблема не только в ConnectionObject, я также попытался передать простой объект, например, TStringlist, а затем использовать назначение для копирования памяти, но он все еще получает AV в приложении # 2.
Если я запустил создание и извлечение в одном приложении, он отлично работает. Когда я беру копию этого приложения и запускаю функцию «создать» в приложении №1 и «извлекаю» в приложении №2, я получаю нарушение доступа.
Общая память не может помочь. Доступ к многоуровневой базе данных - это то, что вам нужно. Средний уровень доступа к базе данных и клиенты разговаривают с этим средним уровнем, скорее прямым в БД. –
Невозможно передать экземпляр объекта через границы процесса. IPC/файлы с общей памятью/памятью не изменят его. Кроме того, даже если вы можете это сделать, соединения с базой данных выполняются по-потоку, и два процесса явно не будут выполняться в одном потоке. –
Почему, по-вашему, вам нужно разделить ADO-соединение? –