PDA

View Full Version : DLLs and classes...



M109uk
07-10-2004, 05:21 PM
Hi all again,

I have a particle system built in a DLL library, and my engine calls procedures to add a new particle system in tot eh world and set the propertise, the basic structure of my particle systems are:



TParticleSystem = Class
//
end;

TParticleSystemList = Class(TList)
// List of TParticleSystem
end;

TParticleSystems = Class(TList)
//
particleSystems: TknParticleSystemList;
end;


I call a function in the library to create a new particle system (TParticleSystems.Add) which in the library does:

function TParticleSystemList.Add: Integer;
var
nItem: TParticleSystem;
begin
nItem := TParticleSystem.Create;
Result := inherited Add(nItem);
end;

this works fine, but if i want to add a particle system to the TParticleSystemList (similar function as above) i get an access violation at address 0000000000!
The violation occurs when i try to add the item to the list

Result := inherited Add(nItem);


I have tried everything, i tried changing from using a Tlist to using a dynamic array, but i get another access violation when i try to change the length of the array.

I then tried to change my particle system library structure, so that it only controls 1 particle system, but i get another access violation but at the beginning when i try to add the particle system.

I'v even tried using pointers and using new() and getmem() but i get the same results.

cairnswm
08-10-2004, 04:43 AM
My immediate respose would be are you sure your list exists yet? Have you initialized it somewhere?

M109uk
08-10-2004, 08:19 AM
The lists definatly exist, they are created when i create the item, with the first method the class it self was a list. And with my second method i know it exisst cause i tested it using the lists count property and expand method and didnt have problems with them.

The thing is i also had the same problem with using a dynamic array, just by calling setlength?!

Is there a memory restriction when using DLLs?

Heres my code incase im missing something:
Theres 2 units and the project file..

kPSystem.dpr:
(i cant see if i have any problems with this ptoject file?!!)

library kPSystem;

{************************************************* ******************************
* Kngine *
* Particle system : engine *
************************************************** *****************************}

uses
FastSharemem,
SysUtils,
Classes,
knVertex,
knParticleSystems,
knParticleSystem;

var
ParticleSystems: TknParticleSystemsList;
CanRender: Boolean = False;

{$R *.res}

procedure knps_Initialize; stdcall;
begin
ParticleSystems := TknParticleSystemsList.Create;
CanRender := True;
end;

procedure knps_Finaliaze; stdcall;
begin
CanRender := False;
If ParticleSystems <> Nil Then
ParticleSystems.Free;
ParticleSystems := Nil;
end;

procedure knps_LoadParticleSystems(const Index: Integer; const Filename: PChar); stdcall;
begin
If Filename = '' Then Exit;
ParticleSystems[Index].LoadFromFile(Filename);
end;

procedure knps_SaveParticleSystems(const Index: Integer; const Filename: PChar); stdcall;
begin
If Filename = '' Then Exit;
ParticleSystems[Index].SaveToFile(Filename);
end;

function knps_AddParticleSystems: Integer; stdcall;
begin
Result := ParticleSystems.Add;
end;

procedure knps_DeleteParticleSystems(const Index: Integer); stdcall;
begin
ParticleSystems.Delete(Index);
end;

procedure knps_ClearParticleSystems(const Index: Integer); stdcall;
begin
ParticleSystems[Index].Clear;
end;

procedure knps_LoadParticleSystem(const Index,pIndex: Integer; const Filename: PChar); stdcall;
begin
ParticleSystems[Index][pIndex].LoadFromFile(Filename);
end;

procedure knps_SaveParticleSystem(const Index,pIndex: Integer; const Filename: PChar); stdcall;
begin
ParticleSystems[Index][pIndex].SaveToFile(Filename);
end;

function knps_AddParticleSystem(const Index: Integer): Integer; stdcall;
begin
Result := ParticleSystems[Index].Add;
end;

procedure knps_DeleteParticleSystem(const Index,pIndex: Integer); stdcall;
begin
ParticleSystems[Index].Delete(pIndex);
end;

procedure knps_Render(const Index: Integer); stdcall;
begin
ParticleSystems[Index].Render;
end;

function knps_ParticleSystemsCount: Integer; stdcall;
begin
Result := ParticleSystems.Count;
end;

function knps_ParticleSystemCount(const Index: Integer): Integer; stdcall;
begin
Result := ParticleSystems[Index].Count;
end;

//---->
// Loads of other functions to get/set propertise
//<----

{************************************************* ******************************
* Exports *
************************************************** *****************************}
exports
// Particle systems initialization, finalization
knps_Initialize, knps_Finaliaze,

// Particle systems functions
knps_LoadParticleSystems, knps_SaveParticleSystems,
knps_AddParticleSystems, knps_DeleteParticleSystems,
knps_ClearParticleSystems,
knps_LoadParticleSystem, knps_SaveParticleSystem,
knps_AddParticleSystem, knps_DeleteParticleSystem,
knps_GetParticleSystemsPosition, knps_GetParticleSystemsRotation,
knps_SetParticleSystemsPosition, knps_SetParticleSystemsRotation,

knps_Render,

knps_ParticleSystemsCount, knps_ParticleSystemCount,

//---->
// Loads of other functions..
//<----
;

begin
end.



knParticleSystem.pas:
(i dont seem to have any problems with this unit, so far..)

unit knParticleSystem;

interface
uses
Classes,
knVertex, knStream;

type
TknParticle = Record
// Several propertise
end;

TknParticleSystem = Class
// Several procedures and propertise
end;

implementation

//---->
// procedures and functions
//<----

end.


knParticleSystems.pas:
(This is the unit that im having problems with)

unit knParticleSystems;

interface
uses
Classes,
knVertex, knStream, knParticleSystem;

type
TknParticleSystems = Class
private
fItems: TList;
function GetItem(Index: Integer): TknParticleSystem;
procedure RenderParticle(Index: Integer);
public
Position: TVertex3f;
Rotation: TVertex3f;
constructor Create;
destructor Destroy; override;

function Add: Integer;
// <---- function Add is the function causing the access violation

procedure Delete(Index: Integer);
function Count: Integer;
procedure Clear;
property Items[Index: Integer]: TknParticleSystem read GetItem; default;
end;

TknParticleSystemsList = Class(TList)
private
function GetItem(Index: Integer): TknParticleSystems;
public
function Add: Integer;
property Items[Index: Integer]: TknParticleSystems read GetItem; default;
end;

var
ParticlesPath: String;

implementation
uses
Math, SysUtils, Dialogs,
knGlobal, knCamera,
dglOpenGL;

//----< TknParticleSystems >----//
function TknParticleSystems.GetItem(Index: Integer): TknParticleSystem;
begin
Result := Nil;
If (Index < 0) Or (Index > Count-1) Then Exit;
Result := TknParticleSystem(fItems[Index]);
end;

constructor TknParticleSystems.Create;
begin
inherited Create;
fItems := TList.Create;
end;

destructor TknParticleSystems.Destroy;
begin
Clear;
fItems.Free;
inherited Destroy;
end;

function TknParticleSystems.Add: Integer;
var
nItem: TknParticleSystem;
begin
ShowMessage('Add new particle system..');
nItem := TknParticleSystem.Create;

Result := Count;

ShowMessage('Add to the list..');
Result := fItems.Add(nItem); // <---- Access violation occours here

ShowMessage('Done..');
end;

procedure TknParticleSystems.Delete(Index: Integer);
begin
If (Index < 0) Or (Index > Count-1) Then Exit;
fItems.Delete(Index);
end;

function TknParticleSystems.Count: Integer;
begin
Result := fItems.Count;
end;

procedure TknParticleSystems.Clear;
begin
fItems.Clear;
end;

//----< TknParticleSystemsList >----//
function TknParticleSystemsList.GetItem(Index: Integer): TknParticleSystems;
begin
Result := Nil;
If (Index < 0) Or (Index > Count-1) Then Exit;
Result := TknParticleSystems(inherited Items[Index]);
end;

function TknParticleSystemsList.Add: Integer;
var
nItem: TknParticleSystems;
begin
ShowMessage('Create new particle systems..');
nItem := TknParticleSystems.Create;

ShowMessage('Add new particle systems..');
Result := inherited Add(nItem);

ShowMessage('Done..');
end;

end.


I just cant see if i have done something wrong, maybe some one else can :lol:

Thanx for any help

cairnswm
11-10-2004, 02:06 AM
I'm sure its not the problem but why do you call inherited all the time? As the SystemsList inherits from TList all those methods are already part of the VMT and will call the same method anyway.

I dont see what the problem is :(

Another suggestion is to look at the initialization and finalization sections of a unit. This is a good place to create and free global variables.

M109uk
11-10-2004, 03:21 AM
Hi,
thanks for the reply..



I'm sure its not the problem but why do you call inherited all the time? As the SystemsList inherits from TList all those methods are already part of the VMT and will call the same method anyway.

I call the inherited class a lot cause a change the class type a lot and it makes it easier. But in this case its because it is inherited from TList, TList has a function called Add already, but i dont want to overload it incase i call the wrong function some where and spend years trying to find it, so i override it and then instead of re-writing all the insert code i use inherited Add, pretty much the same reason for the GetItems function, just lazy i guess :lol:



I dont see what the problem is

Ive gone over it a few more times and i cant understand it..

I think i'l try to re-write it, maybe its a mistake somewhere that i havnt noticed or thought about looking.

Strange because i have written a few more libraries and i have not got the same problem with any of them..



Another suggestion is to look at the initialization and finalization sections of a unit. This is a good place to create and free global variables.

Ok thanks for the suggestion, i will have a look.. I dont think i have any initalization units for the particle system, but i could be wrong, its been a while since i was working on the particle system :roll:

I'l give it a look tomorrow, again thanks for your help 8)

Clootie
11-10-2004, 02:38 PM
As you are using classes in DLL (not in package) try adding "ShareMem" unit to both your main app and DLL library. Althrow from your description this probably will not help, but why not to try?

M109uk
11-10-2004, 04:16 PM
Hey clootie,



As you are using classes in DLL (not in package) try adding "ShareMem" unit to both your main app and DLL library. Althrow from your description this probably will not help, but why not to try?


Thanks for the suggestion, i have just tried adding the ShareMem unit to both the library DPR file and my main applications DPR but i still get the same exception, i also tried a unit called FastShareMem, which is the similar to ShareMem except it doesnt require borlands ShareMem DLL.

I have also rewritten my header file (links the functions to the functions in the DLL) as well as the library file, placed the initilization code into the initialization and finalization sections of the header unit and placed messages in the library to confirm that it is all being created and doing what its supposed to.. Just seems to be the adding function that doesnt work..