Web Development and stuff…

Archive for August, 2009

Writing objects into memory for usage in another application

with one comment

New programming languages like .NET has serialization to send a object from the one to another. In delphi 7 you have to write your own serialization. One of the ways i’ve tried to use is to copy complete objects into memory and restructure the same object in a completely other application. I did this by using FileMappings and Mutexes.  A sample of that code you can find below. Bare in mind that this has been written for my own custom objects but feel free to enhance it.

The code used for this;


unit uMemoryMappings;

interface

uses Classes, Windows, Messages, ShellApi, oObjects, SysUtils, uNetworkResources;

//just a demo object for this code sample
//
type TDemoObject = class(TObject)
private
FIndex : Integer;
FName : String;
public
{}
published
property Index : Integer read FIndex write FIndex;
property Name : String read FName write FName;
end;

//Structure cotnaining the object(s) you want to transfer
//
type TMemoryObject = record
myDemoObject : TDemoObject;
end;

//MXNaming should be unique. Using a GUID ensures the name will be unique.
//
const
_Name   : String = '{CE8DEDB3-638E-475A-870C-DE5F935CB4A5}';
_MXName : String = '{E699BFEA-1C49-49B2-8E9C-CC569E3C2FED}';

var
FileMapping : THandle;
MXHandle    : THandle;

oMemoryObj  : TMemoryObject;

type
PMemoryObj = ^TMemoryObject;

procedure SaveData(rObject : TMemoryObject );
function ReadData : TMemoryObject;
procedure CloseMemoryObjectFile;
procedure CreateMemoryObjectFile;

implementation

//We simply create a file in memory containing the object. Because we might want to use it in a threading model we use
//Mutexes to be sure it won't be overwritten by other threads.
procedure CreateMemoryObjectFile;
begin
FileMapping := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, SizeOf(TMemoryObject), PChar(_Name));
if FileMapping <> 0 then
begin
if GetLastError = ERROR_ALREADY_EXISTS then
begin
CloseHandle(FileMapping);
FileMapping := OpenFileMapping(FILE_MAP_ALL_ACCESS, False, PChar(_Name));
end;
end;

if (FileMapping <> 0) then
MXHandle := CreateMutex(nil, False, PChar(_MXName));

if (FileMapping = 0) or (MXHandle = 0) then
Raise Exception.Create('Error allocating memory');
end;

//Closes the Handles and mutexes
procedure CloseMemoryObjectFile;
begin
if FileMapping <> 0 then
CloseHandle(FileMapping);
if MXHandle <> 0 then
CloseHandle(MXHandle);
end;

//Writes the object to the registered memory block.
procedure SaveData(rObject : TMemoryObject );
var
oData : PMemoryObj;
begin
WaitForSingleObject(MXHandle, INFINITE);
try
oData := MapViewOfFile(FileMapping, FILE_MAP_WRITE, 0, 0, SizeOf(TMemoryObject));
try
oData^.myDemoObject := rObject.myDemoObject;
finally
UnmapViewOfFile(oData);
end;
finally
ReleaseMutex(MXHandle);
end;
end;

//Reads the data stored in the memory block.
function ReadData : TMemoryObject;
var
oData : PMemoryObj;
begin
WaitForSingleObject(MXHandle, INFINITE);
try
oData := MapViewOfFile(FileMapping, FILE_MAP_READ, 0, 0, SizeOf(TMemoryObject));
try
if Assigned(oData^.myDemoObject) then Result.myDemoObject := oData^.myDemoObject;
finally
UnmapViewOfFile(oData);
end;
finally
ReleaseMutex(MXHandle);
end;
end;

end.
del.icio.us Digg DZone reddit SlashDot StumbleUpon Technorati

Written by Alex

August 25th, 2009 at 8:21 am

Posted in Delphi