Board index » delphi » BeforeDestruction not called

BeforeDestruction not called


2005-06-14 10:56:30 PM
delphi118
Hi,
I have a serie of TAutoObjects in a COM-server.
One is create external, the rest create each other in chains.
I have the problem that at setting one to nil in the beforeDestruction
procedure, the one that is set to nil, its BeforeDestruction is not called.
I hope, someone can help me, I have done a lot of these things, and
normally it works fine
Code, I left most of its code out, just wanted to let see the I guess
relevant things
------
This is the one that is walks through its BeforeDestruction
------------------------
uses
ActiveX, Classes, ComObj, StdVcl,PatientExtInfo_TLB;
type
TSubjectOfInvestigationGPIC = class(TAutoObject,
ISubjectOfInvestigationGPIC)
private
FSubjectOfInvestigation : PatientExtendedInformationGPIC;
protected
function Get_SubjectOfInvestigation:
IPatientExtendedInformationGPIC; safecall;
{Declare ISubjectOfInvestigation methods here}
public
procedure AfterConstruction;override;
procedure BeforeDeStruction;override;
end;
implementation
uses ComServ;
procedure TSubjectOfInvestigationGPIC.AfterConstruction;
begin
inherited;
//this is the one which is created inside
FSubjectOfInvestigation := CoPatientExtendedInformationGPIC.Create;
end;
procedure TSubjectOfInvestigationGPIC.BeforeDeStruction;
begin
//and here it should be destroyed, which does not happen, I can also see
//this from memory usage, thus created a gigantic memory leak, because
//other objects in the chain are not destroyed
FSubjectOfInvestigation := nil;
inherited;
end;
function TSubjectOfInvestigationGPIC.Get_SubjectOfInvestigation:
PatientExtendedInformationGPIC;
begin
Result := FSubjectOfInvestigation;
end;
initialization
TAutoObjectFactory.Create(ComServer, TSubjectOfInvestigationGPIC,
Class_SubjectOfInvestigationGPIC,
ciMultiInstance, tmApartment);
end.
---------------------------
Here the object which does not wal through its BeforeConstruction
---------------------------
unit PatientExtendedInformationGPIC;
{$WARN SYMBOL_PLATFORM OFF}
interface
uses
ComObj, ActiveX, PatientExtInfo_TLB, StdVcl,ts14796_TLB;
type
TPatientExtendedInformationGPIC = class(TAutoObject,
IPatientExtendedInformationGPIC)
private
FPatientExtendedInformation : IPatientExtendedInformation;
FRoles : IHL7Set;
protected
function Get_PatientExtendedInformation: IPatientExtendedInformation;
safecall;
function Get_Roles: IUnknown; safecall;
public
procedure BeforeDestruction;override;
procedure AfterConstruction;override;
end;
implementation
uses ComServ;
procedure TPatientExtendedInformationGPIC.AfterConstruction;
begin
inherited;
end;
procedure TPatientExtendedInformationGPIC.BeforeDestruction;
begin
FPatientExtendedInformation := nil;
FRoles := nil;
inherited;
end;
function TPatientExtendedInformationGPIC.Get_PatientExtendedInformation:
IPatientExtendedInformation;
begin
if FPatientExtendedInformation=nil then
FPatientExtendedInformation := CoPatientExtendedInformation.Create;
Result := FPatientExtendedInformation;
end;
function TPatientExtendedInformationGPIC.Get_Roles: IUnknown;
begin
if FRoles=nil then FRoles := COHL7Set.Create;
Result := FRoles;
end;
initialization
TAutoObjectFactory.Create(ComServer, TPatientExtendedInformationGPIC,
Class_PatientExtendedInformationGPIC,
ciMultiInstance, tmApartment);
end.
 
 

Re:BeforeDestruction not called

I want to add, that the BeforeDestruction code is visible in the Delphi
IDE de{*word*81}, it has points and one can put breakpoints. Just to tell
you that the code is not optimized away.
Thanks again
Bert
(remve the X for email)
Bert Verhees writes:
Quote
Hi,

I have a serie of TAutoObjects in a COM-server.

One is create external, the rest create each other in chains.

I have the problem that at setting one to nil in the beforeDestruction
procedure, the one that is set to nil, its BeforeDestruction is not called.

I hope, someone can help me, I have done a lot of these things, and
normally it works fine

Code, I left most of its code out, just wanted to let see the I guess
relevant things
------
This is the one that is walks through its BeforeDestruction
------------------------
uses
ActiveX, Classes, ComObj, StdVcl,PatientExtInfo_TLB;

type
TSubjectOfInvestigationGPIC = class(TAutoObject,
ISubjectOfInvestigationGPIC)
private
FSubjectOfInvestigation : PatientExtendedInformationGPIC;
protected
function Get_SubjectOfInvestigation:
IPatientExtendedInformationGPIC; safecall;
{Declare ISubjectOfInvestigation methods here}
public
procedure AfterConstruction;override;
procedure BeforeDeStruction;override;
end;

implementation

uses ComServ;

procedure TSubjectOfInvestigationGPIC.AfterConstruction;
begin
inherited;
//this is the one which is created inside
FSubjectOfInvestigation := CoPatientExtendedInformationGPIC.Create;
end;

procedure TSubjectOfInvestigationGPIC.BeforeDeStruction;
begin
//and here it should be destroyed, which does not happen, I can also see
//this from memory usage, thus created a gigantic memory leak, because
//other objects in the chain are not destroyed
FSubjectOfInvestigation := nil;
inherited;
end;

function TSubjectOfInvestigationGPIC.Get_SubjectOfInvestigation:
PatientExtendedInformationGPIC;
begin
Result := FSubjectOfInvestigation;
end;

initialization
TAutoObjectFactory.Create(ComServer, TSubjectOfInvestigationGPIC,
Class_SubjectOfInvestigationGPIC,
ciMultiInstance, tmApartment);
end.
---------------------------

Here the object which does not wal through its BeforeConstruction
---------------------------
unit PatientExtendedInformationGPIC;

{$WARN SYMBOL_PLATFORM OFF}

interface

uses
ComObj, ActiveX, PatientExtInfo_TLB, StdVcl,ts14796_TLB;

type
TPatientExtendedInformationGPIC = class(TAutoObject,
IPatientExtendedInformationGPIC)
private
FPatientExtendedInformation : IPatientExtendedInformation;
FRoles : IHL7Set;
protected
function Get_PatientExtendedInformation: IPatientExtendedInformation;
safecall;
function Get_Roles: IUnknown; safecall;
public
procedure BeforeDestruction;override;
procedure AfterConstruction;override;
end;

implementation

uses ComServ;

procedure TPatientExtendedInformationGPIC.AfterConstruction;
begin
inherited;
end;

procedure TPatientExtendedInformationGPIC.BeforeDestruction;
begin
FPatientExtendedInformation := nil;
FRoles := nil;
inherited;
end;

function TPatientExtendedInformationGPIC.Get_PatientExtendedInformation:
IPatientExtendedInformation;
begin
if FPatientExtendedInformation=nil then
FPatientExtendedInformation := CoPatientExtendedInformation.Create;
Result := FPatientExtendedInformation;
end;

function TPatientExtendedInformationGPIC.Get_Roles: IUnknown;
begin
if FRoles=nil then FRoles := COHL7Set.Create;
Result := FRoles;
end;

initialization
TAutoObjectFactory.Create(ComServer, TPatientExtendedInformationGPIC,
Class_PatientExtendedInformationGPIC,
ciMultiInstance, tmApartment);
end.
 

Re:BeforeDestruction not called

Bert Verhees writes:
Quote
I want to add, that the BeforeDestruction code is visible in the Delphi
IDE de{*word*81}, it has points and one can put breakpoints. Just to tell
you that the code is not optimized away.
The AfterConstruction Code is visited. That is another strange thing
Bert
Quote

Thanks again
Bert

(remve the X for email)

Bert Verhees writes:

>Hi,
>
>I have a serie of TAutoObjects in a COM-server.
>
>One is create external, the rest create each other in chains.
>
>I have the problem that at setting one to nil in the beforeDestruction
>procedure, the one that is set to nil, its BeforeDestruction is not
>called.
>
>I hope, someone can help me, I have done a lot of these things, and
>normally it works fine
>
>Code, I left most of its code out, just wanted to let see the I guess
>relevant things
>------
>This is the one that is walks through its BeforeDestruction
>------------------------
>uses
>ActiveX, Classes, ComObj, StdVcl,PatientExtInfo_TLB;
>
>type
>TSubjectOfInvestigationGPIC = class(TAutoObject,
>ISubjectOfInvestigationGPIC)
>private
>FSubjectOfInvestigation : PatientExtendedInformationGPIC;
>protected
>function Get_SubjectOfInvestigation:
>IPatientExtendedInformationGPIC; safecall;
>{Declare ISubjectOfInvestigation methods here}
>public
>procedure AfterConstruction;override;
>procedure BeforeDeStruction;override;
>end;
>
>implementation
>
>uses ComServ;
>
>procedure TSubjectOfInvestigationGPIC.AfterConstruction;
>begin
>inherited;
>//this is the one which is created inside
>FSubjectOfInvestigation := CoPatientExtendedInformationGPIC.Create;
>end;
>
>procedure TSubjectOfInvestigationGPIC.BeforeDeStruction;
>begin
>//and here it should be destroyed, which does not happen, I can also see
>//this from memory usage, thus created a gigantic memory leak, because
>//other objects in the chain are not destroyed
>FSubjectOfInvestigation := nil;
>inherited;
>end;
>
>function TSubjectOfInvestigationGPIC.Get_SubjectOfInvestigation:
>PatientExtendedInformationGPIC;
>begin
>Result := FSubjectOfInvestigation;
>end;
>
>initialization
>TAutoObjectFactory.Create(ComServer, TSubjectOfInvestigationGPIC,
>Class_SubjectOfInvestigationGPIC,
>ciMultiInstance, tmApartment);
>end.
>---------------------------
>
>Here the object which does not wal through its BeforeConstruction
>---------------------------
>unit PatientExtendedInformationGPIC;
>
>{$WARN SYMBOL_PLATFORM OFF}
>
>interface
>
>uses
>ComObj, ActiveX, PatientExtInfo_TLB, StdVcl,ts14796_TLB;
>
>type
>TPatientExtendedInformationGPIC = class(TAutoObject,
>IPatientExtendedInformationGPIC)
>private
>FPatientExtendedInformation : IPatientExtendedInformation;
>FRoles : IHL7Set;
>protected
>function Get_PatientExtendedInformation: IPatientExtendedInformation;
>safecall;
>function Get_Roles: IUnknown; safecall;
>public
>procedure BeforeDestruction;override;
>procedure AfterConstruction;override;
>end;
>
>implementation
>
>uses ComServ;
>
>procedure TPatientExtendedInformationGPIC.AfterConstruction;
>begin
>inherited;
>end;
>
>procedure TPatientExtendedInformationGPIC.BeforeDestruction;
>begin
>FPatientExtendedInformation := nil;
>FRoles := nil;
>inherited;
>end;
>
>function
>TPatientExtendedInformationGPIC.Get_PatientExtendedInformation:
>IPatientExtendedInformation;
>begin
>if FPatientExtendedInformation=nil then
>FPatientExtendedInformation := CoPatientExtendedInformation.Create;
>Result := FPatientExtendedInformation;
>end;
>
>function TPatientExtendedInformationGPIC.Get_Roles: IUnknown;
>begin
>if FRoles=nil then FRoles := COHL7Set.Create;
>Result := FRoles;
>end;
>
>initialization
>TAutoObjectFactory.Create(ComServer,
>TPatientExtendedInformationGPIC, Class_PatientExtendedInformationGPIC,
>ciMultiInstance, tmApartment);
>end.
 

Re:BeforeDestruction not called

Hi,
I have a serie of TAutoObjects in a COM-server.
One is create external, the rest create each other in chains.
I have the problem that at setting one to nil in the beforeDestruction
procedure, the one that is set to nil, its BeforeDestruction is not called.
I hope, someone can help me, I have done a lot of these things, and
normally it works fine.
I want to add, that the BeforeDestruction code is visible in the Delphi
IDE de{*word*81}, it has points on the side and one can put breakpoints.
Just to tell you that the code is not optimized away.
Also, the AfterConstruction Code is visited. That is another strange thing
Code, I left most of its code out, just wanted to let see the I guess
relevant things
------
This is the one that is walks through its BeforeDestruction
------------------------
uses
ActiveX, Classes, ComObj, StdVcl,PatientExtInfo_TLB;
type
TSubjectOfInvestigationGPIC = class(TAutoObject,
ISubjectOfInvestigationGPIC)
private
FSubjectOfInvestigation : PatientExtendedInformationGPIC;
protected
function Get_SubjectOfInvestigation:
IPatientExtendedInformationGPIC; safecall;
{Declare ISubjectOfInvestigation methods here}
public
procedure AfterConstruction;override;
procedure BeforeDeStruction;override;
end;
implementation
uses ComServ;
procedure TSubjectOfInvestigationGPIC.AfterConstruction;
begin
inherited;
//this is the one which is created inside
FSubjectOfInvestigation := CoPatientExtendedInformationGPIC.Create;
end;
procedure TSubjectOfInvestigationGPIC.BeforeDeStruction;
begin
//and here it should be destroyed, which does not happen, I can also see
//this from memory usage, thus created a gigantic memory leak, because
//other objects in the chain are not destroyed
FSubjectOfInvestigation := nil;
inherited;
end;
function TSubjectOfInvestigationGPIC.Get_SubjectOfInvestigation:
PatientExtendedInformationGPIC;
begin
Result := FSubjectOfInvestigation;
end;
initialization
TAutoObjectFactory.Create(ComServer, TSubjectOfInvestigationGPIC,
Class_SubjectOfInvestigationGPIC,
ciMultiInstance, tmApartment);
end.
---------------------------
Here the object which does not wal through its BeforeConstruction
---------------------------
unit PatientExtendedInformationGPIC;
{$WARN SYMBOL_PLATFORM OFF}
interface
uses
ComObj, ActiveX, PatientExtInfo_TLB, StdVcl,ts14796_TLB;
type
TPatientExtendedInformationGPIC = class(TAutoObject,
IPatientExtendedInformationGPIC)
private
FPatientExtendedInformation : IPatientExtendedInformation;
FRoles : IHL7Set;
protected
function Get_PatientExtendedInformation: IPatientExtendedInformation;
safecall;
function Get_Roles: IUnknown; safecall;
public
procedure BeforeDestruction;override;
procedure AfterConstruction;override;
end;
implementation
uses ComServ;
procedure TPatientExtendedInformationGPIC.AfterConstruction;
begin
inherited;
end;
procedure TPatientExtendedInformationGPIC.BeforeDestruction;
begin
FPatientExtendedInformation := nil;
FRoles := nil;
inherited;
end;
function TPatientExtendedInformationGPIC.Get_PatientExtendedInformation:
IPatientExtendedInformation;
begin
if FPatientExtendedInformation=nil then
FPatientExtendedInformation := CoPatientExtendedInformation.Create;
Result := FPatientExtendedInformation;
end;
function TPatientExtendedInformationGPIC.Get_Roles: IUnknown;
begin
if FRoles=nil then FRoles := COHL7Set.Create;
Result := FRoles;
end;
initialization
TAutoObjectFactory.Create(ComServer, TPatientExtendedInformationGPIC,
Class_PatientExtendedInformationGPIC,
ciMultiInstance, tmApartment);
end.
 

Re:BeforeDestruction not called

Solved, the reference count did not reach 0, because of a circular
reference between two interfaces.
Just thought, write it down, maybe someone lese have use from it.
Bert
Bert Verhees writes:
Quote
Hi,

I have a serie of TAutoObjects in a COM-server.

One is create external, the rest create each other in chains.

I have the problem that at setting one to nil in the beforeDestruction
procedure, the one that is set to nil, its BeforeDestruction is not called.

I hope, someone can help me, I have done a lot of these things, and
normally it works fine.

I want to add, that the BeforeDestruction code is visible in the Delphi
IDE de{*word*81}, it has points on the side and one can put breakpoints.
Just to tell you that the code is not optimized away.

Also, the AfterConstruction Code is visited. That is another strange thing

Code, I left most of its code out, just wanted to let see the I guess
relevant things
------
This is the one that is walks through its BeforeDestruction
------------------------
uses
ActiveX, Classes, ComObj, StdVcl,PatientExtInfo_TLB;

type
TSubjectOfInvestigationGPIC = class(TAutoObject,
ISubjectOfInvestigationGPIC)
private
FSubjectOfInvestigation : PatientExtendedInformationGPIC;
protected
function Get_SubjectOfInvestigation:
IPatientExtendedInformationGPIC; safecall;
{Declare ISubjectOfInvestigation methods here}
public
procedure AfterConstruction;override;
procedure BeforeDeStruction;override;
end;

implementation

uses ComServ;

procedure TSubjectOfInvestigationGPIC.AfterConstruction;
begin
inherited;
//this is the one which is created inside
FSubjectOfInvestigation := CoPatientExtendedInformationGPIC.Create;
end;

procedure TSubjectOfInvestigationGPIC.BeforeDeStruction;
begin
//and here it should be destroyed, which does not happen, I can also see
//this from memory usage, thus created a gigantic memory leak, because
//other objects in the chain are not destroyed
FSubjectOfInvestigation := nil;
inherited;
end;

function TSubjectOfInvestigationGPIC.Get_SubjectOfInvestigation:
PatientExtendedInformationGPIC;
begin
Result := FSubjectOfInvestigation;
end;

initialization
TAutoObjectFactory.Create(ComServer, TSubjectOfInvestigationGPIC,
Class_SubjectOfInvestigationGPIC,
ciMultiInstance, tmApartment);
end.
---------------------------

Here the object which does not wal through its BeforeConstruction
---------------------------
unit PatientExtendedInformationGPIC;

{$WARN SYMBOL_PLATFORM OFF}

interface

uses
ComObj, ActiveX, PatientExtInfo_TLB, StdVcl,ts14796_TLB;

type
TPatientExtendedInformationGPIC = class(TAutoObject,
IPatientExtendedInformationGPIC)
private
FPatientExtendedInformation : IPatientExtendedInformation;
FRoles : IHL7Set;
protected
function Get_PatientExtendedInformation: IPatientExtendedInformation;
safecall;
function Get_Roles: IUnknown; safecall;
public
procedure BeforeDestruction;override;
procedure AfterConstruction;override;
end;

implementation

uses ComServ;

procedure TPatientExtendedInformationGPIC.AfterConstruction;
begin
inherited;
end;

procedure TPatientExtendedInformationGPIC.BeforeDestruction;
begin
FPatientExtendedInformation := nil;
FRoles := nil;
inherited;
end;

function TPatientExtendedInformationGPIC.Get_PatientExtendedInformation:
IPatientExtendedInformation;
begin
if FPatientExtendedInformation=nil then
FPatientExtendedInformation := CoPatientExtendedInformation.Create;
Result := FPatientExtendedInformation;
end;

function TPatientExtendedInformationGPIC.Get_Roles: IUnknown;
begin
if FRoles=nil then FRoles := COHL7Set.Create;
Result := FRoles;
end;

initialization
TAutoObjectFactory.Create(ComServer, TPatientExtendedInformationGPIC,
Class_PatientExtendedInformationGPIC,
ciMultiInstance, tmApartment);
end.
 

Re:BeforeDestruction not called

Quote
I have a serie of TAutoObjects in a COM-server.

One is create external, the rest create each other in chains.

I have the problem that at setting one to nil in the
beforeDestruction procedure, the one that is set to nil, its
BeforeDestruction is not called.

I hope, someone can help me, I have done a lot of these things, and
normally it works fine.

I want to add, that the BeforeDestruction code is visible in the
Delphi IDE de{*word*81}, it has points on the side and one can put
breakpoints. Just to tell you that the code is not optimized away.

Also, the AfterConstruction Code is visited. That is another strange
thing
Are you certain that there are no circular references? These render the
reference counting mechanism completely useless, because it can't
detect them.