JWSCL provides access to auto pointers or objects. It means that allocated space or objects are automtically destroyed/freed as soon as the auto object runs out of scope. What is a scope? A scope exists as long as the (I say) parent object exists. Parent objects can be:

  1. The process. The auto pointer and thus the object exist as long as the process runs. The object will be destroyed when the process is destroyed.
  2. A class or record. The auto pointer exists as long as the class instance exists. If the instance is freed the managed auto pointer object will be freed as well.

What is not a parent object?

  1. begin end. In contrast to C++, a begin/end construct does not allow to create a variable scope. You have to create a new function do achieve the same effect.
  2. A pointer to an object. Auto pointer to any object (class, record, variable) will not be automatically destroyed. You have to free the memory manually (Dispose, FreeMem) to let the auto pointer take effect.

The current release only allows to create or wrap objects. It is done by the methods of TJwAutoPointer.

The following sample shows how to avoid to manually call free. It uses the Wrap method of TJwAutoPointer to activate the managed pointer mechanism. There is no method to undo this call.

procedure X;
var
  ManagedObject : TJwSecurityID;
  AutoPtr : IJwAutoPointer;
begin
  ManagedObject := TJwSecurityID.Create();
  AutoPtr := TJwAutoPointer.Wrap(ManagedObject);

//no need to free ManagedObject
end;

The advantage of the auto pointer approach is that we do not need to call Free for every possible exit. Even exceptions cannot avoid that the managed object is destroyed.
The next sample demonstrates this fact.

procedure X;
var
  ManagedObject : TJwSecurityID;
  AutoPtr : IJwAutoPointer;
begin
  ManagedObject := TJwSecurityID.Create();
  AutoPtr := TJwAutoPointer.Wrap(ManagedObject);

  if DoExit then
   exit;

  if Error then
   raise Exception.Create();
  …
  //no need to free ManagedObject
end;

The same way can be used to add the IJwAutoPointer variable into classes and records.

uses
  SysUtils,
  JwsclComUtils;
type
  TMyClass = class
  public
    N : String;
    x : IJwAutoPointer;
    constructor Create(Name : String);
    destructor Destroy; override;
  end;

TMyRecord = record
  x : IJwAutoPointer;
end;

constructor TMyClass.Create(Name: String);
begin
  inherited Create;
  Writeln(‘Create :’,Name);
  N := Name;
end;

destructor TMyClass.Destroy;
begin
  Writeln(‘DesTMyRecordoy: ‘,N);
  inherited;
end;

procedure X;
var Y,Z : TMyClass;
begin
  Y := TMyClass.Create(’1′);
  Z := TMyClass.Create(’2′);
  Y.x := TJwAutoPointer.Wrap(Z);

  Y.Free;
end;

procedure Y(UseDispose : Boolean);
var
  L : TMyRecord;
  pL : ^TMyRecord;
  Y : TMyClass;
begin
  new(pL);
  Y := TMyClass.Create(’1′);
  PL.x := TJwAutoPointer.Wrap(Y);

  writeln;
  if UseDispose  then
   dispose(PL);
end;

A call to X returns:

Create :1
Create :2
Destroy: 1
Destroy: 2

As you can see, the managed object (Name : “2″) is shortly destroyed after the parent object is destroyed. You should know about this fact, because accessing the parent object will fail (if you are luck) in an exception.

A call to Y(false) returns

Create :1

A call to Y(true) returns

Create :1
Destroy: 1

The next release of JWSCL will bring support for pointers created by New and GetMem as well as LocalAlloc. It will also implement thread safe locking mechanisms.

[Update]

There is no need to save the COM object if you want to keep the object only alive in a single function.
Just wrap it.

procedure X;
var Y,Z : TMyClass;
begin
  Y := TMyClass.Create(’1′);
  TJwAutoPointer.Wrap(Y);
end;

You even can wrap it several times. All wrapped up instances will be freed, regardeless of the variable’s name.

procedure X;
var Y,Z : TMyClass;
begin
  Y := TMyClass.Create(’1′);
  TJwAutoPointer.Wrap(Y);

  Y := TMyClass.Create(’2′);
  TJwAutoPointer.Wrap(Y);
end;

Of course you can’t access the first object anymore. But sometimes it comes quite handy.